Сценарии использования пустой коллекции Java и заполнение ям

Java задняя часть база данных внешний интерфейс
Сценарии использования пустой коллекции Java и заполнение ям

Узнайте, как создать пустую коллекцию в Java сегодня, а также некоторые сценарии использования и связанные с ними ямы пустых коллекций. Вы могли бы спросить, кажется, что здесь не о чем говорить, разве это не пустое множество?newНу, это какnew ArrayList<String>()Не было бы нормально создать такой? На самом деле это тоже способ создания пустой коллекции, но сегодня я расскажу о создании пустой коллекции другим способом, и о разнице между двумя способами.

1. ПройтиCollections.emptyList()Создать пустую коллекцию

Класс инструментов для коллекций Java предоставляет ряд статических методов для создания коллекций, включая создание связанных с синхронизацией потоков.Collections.synchronizedXXX()методы, пустые коллекцииCollections.emptyXXX()метод. Созданная таким образом пустая коллекция, поскольку она пуста, не позволяет добавлять и удалять элементы в коллекцию, то есть нельзя вызывать соответствующиеadd()иremove()метод, позвольте мне видетьCollectionsЧасть исходного кода класса для создания пустой коллекции:

public static final List EMPTY_LIST = new EmptyList<>();

......

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

вы найдете вышеemptyList()По умолчанию метод возвращает предыдущую статическую переменнуюEMPTY_LIST, можно сказать, посколькуEMPTY_LISTдаstaticДа, тогда я прямо передаюCollections.EMPTY_LISTНичего страшного, если вы не можете его получить, да, вы можете это сделать, но в некоторых сценариях, требующих дженериков, вызовитеemptyList()Методы обеспечивают соответствующую общую поддержку.

Так почему же этот способ не добавляет и не удаляет элементы? ПосмотримEmptyListКак определяется внутренний класс:

// 继承自AbstractList抽象类
private static class EmptyList<E>
    extends AbstractList<E>
    implements RandomAccess, Serializable {
    
    private static final long serialVersionUID = 8842843931221139166L;
    public Iterator<E> iterator() {
        return emptyIterator();
    }
    public ListIterator<E> listIterator() {
        return emptyListIterator();
    }
    public int size() {return 0;}
    public boolean isEmpty() {return true;}
    public boolean contains(Object obj) {return false;}
    public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
    public Object[] toArray() { return new Object[0]; }
    
    public <T> T[] toArray(T[] a) {
        if (a.length > 0)
            a[0] = null;
        return a;
    }

    public E get(int index) {
        throw new IndexOutOfBoundsException("Index: "+index);
    }

    public boolean equals(Object o) {
        return (o instanceof List) && ((List<?>)o).isEmpty();
    }

    public int hashCode() { return 1; }

    @Override
    public boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        return false;
    }
    @Override
    public void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
    }
    @Override
    public void sort(Comparator<? super E> c) {}

    // Override default methods in Collection
    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
    }

    @Override
    public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
    // Preserves singleton property
    private Object readResolve() {
        return EMPTY_LIST;
    }
}

Из приведенного выше исходного кода мы можем найтиEmptyListКласс не переопределяет соответствующий родительский классadd()илиremove()метод, то при вызове методаadd()метод будет вызываться по умолчаниюAbstractListизadd()метод, хорошо, тогда давайте посмотрим на родительский классAbstractListизadd()Как реализован метод:

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}
public E remove(int index) {
    throw new UnsupportedOperationException();
}

К сожалению, родительский класс бросает вас напрямуюUnsupportedOperationExceptionНенормальный, так что, я думаю, черезCollectionsТакже разумно создать пустую коллекцию, в которую нельзя добавлять и удалять элементы, потому что это пустая коллекция, пустая, так зачем добавлять и удалять операции. Ниже описаны сценарии использования этого метода.

2. Простые сценарии использования

Часто используется в веб-разработкеrest + jsonКогда внешний интерфейс вызывает интерфейс, интерфейсу может потребоваться вернуть пустой набор внешнему интерфейсу.Collections.emptyXXX()очень подходит, потому что с помощьюnew ArrayList()Инициализация также займет соответствующие ресурсы.

Для иллюстрации вызоваadd()Метод выдаст исключение, напишите небольшой тест ниже:

public class RemoveIfTest {
    private static List<Object> list = Collections.emptyList();
    public static void main(String[] args) {
    	
    	list.add("one1");
    	list.add("one2");
    	list.add(1);
    	list.add(2);
    	list.add(new Object());
    	
    	System.err.println(Arrays.toString(list.toArray()));
    }
}

Вывод программы:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)
    at com.example.RemoveIfTest.main(RemoveIfTest.java:17)

3. Резюме

В общем, нам не нужно ломать голову над вопросом, как создать пустую коллекцию, главное помнить, чтоCollections.emptyXXX()Созданная пустая коллекция не может выполнять операции добавления и удаления и ее принципы, чтобы избежать ошибок в будущем, но на самом деле, даже если вы используете ее неправильно, отладка вашего кода несколько раз, вероятно, найдет проблему, но эта статья может помочь вам сохранить Перейти сюда для процесса поиска ошибок!

Категории