【Java】ArrayList<>()和Collections.emptyList()的区别
一、先看源码
1.ArrayList<>()
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
构造一个具有指定初始容量的空列表。
参数:
initialCapacity – 列表的初始容量
抛出:
IllegalArgumentException – 如果指定的初始容量为负
这里我们可以发现,如果初始化的size是0,就会得到一个EMPTY_ELEMENTDATA
。
2.Collections.emptyList()
Collections类官方的注释是这样的
此类仅包含对集合进行操作或返回集合的静态方法。它包含对集合进行操作的多态算法、“包装器”,它返回由指定集合支持的新集合,以及其他一些零碎的东西。
如果提供给它们的集合或类对象为空,则该类的方法都将抛出 NullPointerException。
此类中包含的多态算法的文档通常包括对实现的简要说明。此类描述应被视为实现说明,而不是规范的一部分。只要遵守规范本身,实现者应该可以随意替换其他算法。 (例如,sort 使用的算法不一定是归并排序,但它必须是稳定的。)
此类中包含的“破坏性”算法,即修改它们操作的集合的算法,如果集合不支持适当的变异原语(例如 set 方法),则指定为抛出 UnsupportedOperationException。如果调用对集合没有影响,则这些算法可能(但不是必需)抛出此异常。例如,对已排序的不可修改列表调用 sort 方法可能会也可能不会抛出 UnsupportedOperationException。
Collections是聚合的工具类,我们调用的emptyList()
的源码如下
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
- 1
- 2
- 3
- 4
其中EMPTY_LIST
实例化了一个EmptyList
,EmptyList
的源码如下
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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
二、相同和不同
1.相同点
很显然,ArrayList<>()
和Collections.emptyList()
得到的结果是一样的,都是空的ArrayList。
2.不同点
Collections.emptyList()在源码注释中提到,他是类型安全不可变的空列表。
ArrayList<>()则是没有定义长度的列表,也就是说他的长度是可变的,并不是完全为了返回空列表准备。
从前面的源码看,如果定义的时候确定size设置为0,就会运行
this.elementData = EMPTY_ELEMENTDATA;
- 1
这样就会得到一个元素都空的列表了。
3.ArrayList<>()做了什么
ArrayList<>()会在内存开辟空间,以便准备写入后续可能写入的数据。
4.Collections.emptyList()
Collections.emptyList()
则不会,从上面的源码看,他是Collections的内部类,并不会占用多余的内存。
三、总结
如果你想返回空列表,希望你使用Collections.emptyList()
,因为这样能够更少的减少内存浪费。
遇到问题多看看源码,答案就在问题里。
文章来源: coderfix.blog.csdn.net,作者:小雨青年,版权归原作者所有,如需转载,请联系作者。
原文链接:coderfix.blog.csdn.net/article/details/122217683
- 点赞
- 收藏
- 关注作者
评论(0)