Узнайте, как создать пустую коллекцию в 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()Созданная пустая коллекция не может выполнять операции добавления и удаления и ее принципы, чтобы избежать ошибок в будущем, но на самом деле, даже если вы используете ее неправильно, отладка вашего кода несколько раз, вероятно, найдет проблему, но эта статья может помочь вам сохранить Перейти сюда для процесса поиска ошибок!