前言
Java中ArrayList或许是我们平时开发最常用的一个集合类了,其次是HashMap,基本上满足了业务开发的绝大多数场景。今天要说的就是Collections.emptyList()和new ArrayList()的区别以及注意事项。
先来一段代码
运行main方法,会有如下输出:
很显然,Collections.emptyList()会抛出“java.lang.UnsupportedOperationException”的异常。
使用及区别
日常开发中,我们经常会写一个方法,返回一个集合。当这个方法返回的数据为空时候,通常我们会返回一个Collections.emptyList(),而不是null。这样方法调用者就不用担心集合是否null了。比如这样的:
突然有一天,有一个同事调用了你的这个方法,然后再加入自己的数据:
就会可能出现如下几种情况:
- 自测时候被发现:幸亏本大神自测发现,不然测试那帮家伙肯定发现不了;
- 被测试发现:那是因为没有数据,好了好了,我兼容一下好了;
- 代码上线了:不断的抛出异常,不断的报警,大多数用户访问的页面出现系统异常。
很不幸,我们真的成功的走到了第三步,然后被用户反应出来了(因为只有部分用户在没有数据的情况下会产生这个bug)。。。
说了这么多,那既然Collections.emptyList()有问题我就直接用new ArrayList()没问题了吧?
是的!没有问题,但是总感觉low了点?
所以,搞清楚二者的区别以及适用场景才是一个爱学习的程序员要做的事情。
先看Collections.emptyList()方法的源码:
返回一个不可变的空集合,那如何是不可变的呢?
原来是EmptyList类没有实现add()和remove()方法。
那使用这个方法的意义是什么?或者说JDK为什么要提供这个方法呢?
大家肯定看到了EMPTY_LIST这个类常量!
它在Collections类里面属于静态常量,静态常量什么概念?在JVM虚拟机加载完毕时候就已经存在了,当我们调用这个方法的时候不需要再去创建一个新的List对象了,减少了内存开销。所以当你的方法调用频率很高,并且可能会返回空集合时候,使用Collections.emptyList()会提高你的代码性能,降低内存开销。
总结
- Collections.emptyList()返回了一个不可变的空集合,不支持集合数据修改操作,多次调用不会额外增加内存消耗;
- new ArrayList()每次都会创建一个对象,需要内存开销;
- Collections.emptyList()使得调用者不需要去判断返回是否为null,但是需要注意这个集合不可变;
- EMPTY_LIST和emptyList()的唯一区别就是EMPTY_LIST没有支持泛型,需要强转一下;
- emptySet()、emptyMap()和emptyList()是一个道理;
- Java 9中的List.of()简化了emptyList()的使用。