【Java】ArrayList<>()和Collections.emptyList()的区别

举报
小雨青年 发表于 2022/03/28 23:24:48 2022/03/28
【摘要】 一、先看源码 1.ArrayList<>() public ArrayList(int initialCapacity) { if (initialCapacity &...

一、先看源码

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实例化了一个EmptyListEmptyList的源码如下

    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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。