Java之Collections.emptyList()、emptySet()、emptyMap()的作用和好处以及要注意的地方。

先说明一下好处有哪些:
1,如果你想 new 一个空的 List ,而这个 List 以后也不会再添加元素(有大坑,看下面更新)

那么就用 Collections.emptyList() 好了。
new ArrayList() 或者 new LinkedList() 在创建的时候有会有初始大小,多少会占用一内存。
每次使用都new 一个空的list集合,浪费就积少成多,浪费就严重啦,就不好啦
2,为了编码的方便。
比如说一个方法返回类型是List,当没有任何结果的时候,返回null,有结果的时候,返回list集合列表。
那样的话,调用这个方法的地方,就需要进行null判断。使用emptyList这样的方法,可以方便方法调用者。返回的就不会是null,省去重复代码。

注意的地方:
这个空的集合是不能调用.add(),添加元素的。因为直接报异常。因为源码就是这么写的:直接抛异常。

哦,Collections里面没这么写,但是EmptyList继承了AbstractList这个抽象类,里面简单实现了部分集合框架的方法。
这里面的add方法最后调用的方法体,就是直接抛异常。
throw new UnsupportedOperationException();
这么解释add报异常就对啦。

下面简单看下这个源码:

    /**
     * Collections 类里面的方法如下,一步步往下看就是啦
     */
    public static final <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
    }
	//。。。。。
    /**
     * Collections 类里面的方法如下,一步步往下看就是啦
     */
    public static final List EMPTY_LIST = new EmptyList<>();
	//。。。。。
	 /**
     * Collections里面的一个静态内部类
     */
    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; }

        // Preserves singleton property
        private Object readResolve() {
            return EMPTY_LIST;
        }
    }

除了这个emptyList,之外,还有类似的,emptyMap,emptySet等等。具体看下图,都是一个套路。

(2017/08/28 更新)

看下面的代码,咱先弄个empty出来,然后,可能有需求要继续在这个空集合里面添加内容。那么,bug就来啦。

    /**
     * 测试这个空集合是某个Java bean 的某个属性的时候的操作,也是不能add的
     */
    private static void testModelEmptyField() {
        Car car = new Car();
        car.setBoys(Collections.emptyList());
        car.getBoys().add("sss");
    }

    /**
     * Collections.emptyMap()  返回的空集合是不能进行put的
     */
    private static void testEmptyMap() {
        Map<String,String> map = Collections.emptyMap();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ":"+ entry.getValue());
        }
        map.put("a","a");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ":"+ entry.getValue());
        }
    }

    /**
     * Collections.emptyList()  返回的空集合是不能进行add的
     */
    private static void testEmptyList() {
        List<String> list = Collections.emptyList();
        for (String s : list) {
            System.out.println(s);
        }
        //异常
        list.add("1");
        for (String s : list) {
            System.out.println(s);
        }
    }

具体出的bug,看下面的截图。

阿弥陀佛,算了 ,这个咱还是不用了吧。

很危险的,分分钟代码就bug啦。这个不好,不好。。。不用啦,了解下就得啦。

为什么不推荐使用:

因为这个是返回了个默认集合,这个集合不是null了,其他人在使用你这个返回值的时候,省去了判断null这一步。

假设,这有个接盘的老铁,一看,哎这个方法始终都是返回一个集合的,那么万一需求变了,要是空集合的时候,给这个空集合添加个默认值,或者怎么滴,反正,就是有进一步的操作,要往这个返回的集合里面添加东西。那么,在这个接盘的老铁写代码的阶段,这个代码是不会报错的。代码看上去一切OK,但是,一旦,项目运行,这个代码运行了,就会出现我最后一个图的,异常了。要是这个老铁是个新人或者说不了解,你这个“高级装逼”操作的返回集合有这个问题的话,打死他,他也不知道,他这个异常问题,出在哪里。

有时候,不是说你代码写的多牛逼,又是设计模式,又是各种高科技的使用,这样的话,你的代码确实看起来牛逼,但是,毕竟项目不是一个人在搞,要考虑整体的水平,不然你使用了一些华丽的高科技,其实一些简单的操作就可以实现类似的功能的话,那么,你这个华丽装逼,确实给队友带来了一定的麻烦,就像王者荣耀一样,你再牛逼,你能一打9么。毕竟是个5v5的游戏嘛,工作也是如此的嘛。自己牛逼,懂的多了,要带着队友赢嘛。

还有啊。

观众老铁,你搜索到这个文章,难道不是因为已经出了这个bug了么?或者说,你在搜索之前,你知道这个装逼操作的影响么,知道了的话,也没必要搜索了呀。

我刚刚开始也觉得这个还是不错的,毕竟有句话叫“存在即合理”,但是发现这个确实会“挖个坑,等待有缘人往里面蹦”,所以,后面又更新了下文章:不推荐使用啦。

  • 19
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 26
    评论
Collections.emptyMap()是Collections的一个静态方法,用于返回一个空的、不可变的Map对象。\[1\]这个方法的好处是可以方便地获取一个空的Map对象,而无需自己创建一个空的Map实例。这在某些情况下非常有用,比如当你需要一个空的Map作为方法的返回值或者作为参数传递给其他方法时。使用Collections.emptyMap()可以避免创建一个新的空Map对象,节省了内存和资源的开销。\[2\]下面是一个使用Collections.emptyMap()的例子: ```java import java.util.*; public class EmptyMapExample { public static void main(String\[\] args) { // 使用emptyMap()方法获取一个空的Map对象 Map<String, Integer> map = Collections.emptyMap(); // 输出空的Map对象 System.out.println("map: " + map); } } ``` 以上代码会输出:map: {},表示获取到的是一个空的Map对象。\[3\] #### 引用[.reference_title] - *1* *2* [Collection工具类的 emptyMap() 、emptySet() 、emptySet()](https://blog.csdn.net/vansbelove/article/details/72416918)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [java 方法 示例_Java CollectionsEmptyMap()方法与示例](https://blog.csdn.net/cumt30111/article/details/107797248)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值