Java 9 新特性—新增只读集合和工厂方法

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

对于大多数小伙伴而言,其实是很少使用只读集合的,甚至有蛮大一部分小伙伴可能都没有听过这个,大部分使用集合无非就是如下两种方式:

List<String> list = new ArrayList();
or
List<String> list = getXxxList();

其实只读集合在编程中还是蛮有用处的,首先只读就意味着不可变,即线程安全,在使用它的过程中我们无需使用同步机制来保护其内部状态。同时只读集合通常比可变集合更加高效。因为它们是不可变的,不需要支持修改操作,因此在内部数据结构上可以进行优化,这可以提高数据访问的速度和降低内存开销。

这篇文章我们来看看 Java 引入的一项重要特性—只读集合和工厂方法。

Java 8 创建不可变集合

在 Java 9 之前要创建一个只读集合,通常需要通过将可变集合转换为不可变集合的方式来实现,即使用Collections.unmodifiableXXX(),其中XXX可以是ListSetMap,例如要创建一个只读 List:

    @Test
    public void test() {
        List<String> list = new ArrayList<>();
        list.add("死磕 Java 新特性");
        list.add("死磕 Netty");

        // 转换为只读集合
        list = Collections.unmodifiableList(list);
    }

使用 Collections.unmodifiableList() 将 List 转换为不可变集合,如果我们使用 add() 来添加元素,会报 UnsupportedOperationException 异常信息

这种方式虽然有效,但是比较麻烦,它需要额外的步骤来处理,而且容易出错。

Java 9 创建不可变集合

为了解决 Java 8 的问题,Java 9 引入不可变集合和对应的工厂方法,目的就在于提供更安全、更高效的方式来创建不可变集合,同时确保原始集合无法被修改。

ListSetMap 都提供了对应的工厂方法来创建不可变集合,我们这里列出 List 的:

static <E> List<E>  of()
static <E> List<E>  of(E e1)
static <E> List<E>  of(E e1, E e2)
static <E> List<E>  of(E e1, E e2, E e3)
static <E> List<E>  of(E e1, E e2, E e3, E e4)
static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5)
static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
//varargs
static <E> List<E>  of(E... elements)

看到这么多重载方法是不是有点儿懵逼,感觉是不是只需要有 of() 和 of(E... elements) 这两个方法就可以了,从实现的效果上来说,确实是可以。of(E... elements) 确实是一个非常灵活的方法,可以适用于多种情况,但是Java 9 引入多个重载的 List.of() 方法并不是为了提供不同数量的参数选择的灵活性,而是为了性能和可读性的考虑。每个 List.of()方法的重载版本都是针对特定的参数数量进行了优化,以提高性能和代码清晰度。当使用 of(E... elements) 时,Java运行时需要创建一个数组以容纳传递的元素(Java 的可变参数,会被编译器转型为一个数组),这可能会引入一些额外的开销,尤其是在创建小型 List 时。而多个重载的 List.of() 方法避免了这种开销,因为它们直接接受参数,而无需创建数组。所以,看着懵逼,但是性能杠杠的。

不可变的 List 具有如下几个特征:

  1. 这些列表是不可变的。调用任何改变 List 的方法(如add()remove()replaceAll()clear()),都会抛出 UnsupportedOperationException
  2. 它们不允许 null 元素。 尝试添加 null 元素将导致 NullPointerException
  3. 列表中元素的顺序与提供的参数或提供的数组中的元素的顺序相同。

对于 Set 和 Map 大明哥就不介绍了,小伙们自己去探索下!

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值