当前位置: 首页 > 科技观察

跟着Guava学Java的不可变集合_0

时间:2023-03-19 17:39:36 科技观察

什么是不可变集合?不可变集合英文叫做immutable。顾名思义,集合不能被修改。集合的数据项是在创建时提供的,并且在其整个生命周期内都是不可变的。为什么要使用不可变集合?第一:防御性编程要求我有一个集合,你用,鬼知道你会不会乱来,往集合里加不合适的元素,或者随便删元素,我不担心,是的,我就是不信你,我是我收藏的主人,让我给你一个不可变的,这样你就不能乱动我的收藏,我就放心了,也不担心你的操作给我带来风险。官方解释:defense,防御性编程,听起来高级吗?第二:线程安全不买不杀!集合是不可变的,不让你有变化,变化是不可能的。如果没有变化,就不会有竞争条件,并且对尽可能多的线程来说都是一样的。安全是绝对安全的。第三:节省开销不需要支持可变性,可以尽可能节省空间和时间。所有不可变集合实现比可变集合更有效地使用内存。JDK9之前Collections的实现提供了一套方法将可变集合封装成不可变集合:但是这玩意有个问题,例如:Listlist=newArrayList();list.add("一个");list.add("b");list.add("c");ListunmodifiableList=Collections.unmodifiableList(list);list.add("d");System.out.println(unmodifiableList);这个输出的结果实际上是[a,b,c,d]。什么?那不是改变吗?我想要的是一个不可变的集合,这狗屎。有兄弟说,我能不能把list的引用去掉?Listlist=newArrayList();list.add("a");list.add("b");list.add("c");ListunmodifiableList=Collections.unmodifiableList(list);list.add("d");列表=空;System.out.println(unmodifiableList);呵呵,不行,输出还是[a,b,c,d]真是坑爹,你发现了,Coding也比较麻烦,还得用Collections间接传递。Collections.unmodifiableList实现的不是真正的不可变集合。当原始集合被修改时,不可变集合也会发生变化。另外,它返回的数据结构本质上还是原来的集合类,所以它的操作开销,包括并发修改检查,哈希表中额外的数据空间,都和原来的集合是一样的。由于这些问题,JDK9引入了一些新的生成不可变集合的方法,比如:List.ofSet.ofMap.of...确实可以直接生成不可变集合,而且编码更方便:ListimmutableList=List.of("a","b","c");如果要修改集合,会抛出异常java.lang.UnsupportedOperationException:immutableList.add("d");但是;Listlist=newArrayList();list.add("a");list.add("b");list.add("c");List>list1=List.of(list);list.add("d");System.out.println(list1);上面代码的输出仍然是:[a,b,c,d];当然,我们并不是说别人的api不对,他们就是这么设计的(信不信由你),但我心里不舒服。如果你不小心,你可能会犯错误。本来就是防御性编程,有可能变成失控编程。再说一次,不是JDK设计错了,他们就是这么设计的,明白吗?当然也有谷歌的工程师不爽,下面就介绍一下拿起键盘自己动手解决问题的谷歌工程师写的guava是如何解决问题的。来到Guava,我们就按照上面的例子,自己写一个Guava版本:Listlist=newArrayList();list.add("a");list.add("b");list.add("c");ImmutableListstrings=ImmutableList.copyOf(list);list.add("d");System.out.println(字符串);输出最终如我所愿:也是[a,b,c]。它在命名、语义、结果和代码可读性方面是否比JDK版本好很多?这样的代码让我觉得世界美好了一点。美好的东西都想拥有,但问题来了,Guava针对哪些集合提供了哪些对应的不可变集合类呢,这里我们给大家整理了一下:可变集合接口属于JDK还是Guava不可变版本CollectionJDKImmutableCollectionListJDKImmutableListSetJDKImmutableSetSortedSet/NavigableSetJDKImmutableSortedSetMapJDKImmutableMapSortedMapJDKImmutableSortedMapMultisetGuavaImmutableMultisetSortedMultisetGuavaImmutableSortedMultisetMultimapGuavaImmutableMultimapListMultimapGuavaImmutableListMultimapSetMultimapGuavaImmutableSetMultimapBiMapGuavaImmutableBiMapClassToInstanceMapGuavaImmutableClassToInstanceMapTableGuavaImmutableTable介绍Severalmethods:theofmethod,theusageisinthesameline,itisthecopyOfusedtobuildthecollection,itappearedintheaboveexample,theofficialdocumentsaysitisintelligent,forexample,itcanjudgewhethertheparameterisanimmutableobject,soastoavoidcopyingJDK10Listlist=newArrayList();list.add("a");list.add("b");list.add("c");Liststrings=List.copyOf(list);list.add("d");System.out.println(strings);Theabovecodeoutputs[a,b,c]inversionsaboveJDK10,mainlybecausethecopyOfmethodisonlyavailableinversionsabove10.Yousee,JDKhasalsobeenimproving,soifyouareusingJDK10andabove,itisoptionaltouseGuavaforthisspecificfunctionpoint.最后综合比较,个人感觉Guava的API在不可变集合的操作上比较好用。当然,库的使用因人而异,使用JDK原生的是没有问题的。毕竟依赖少了,学习成本也低了。小的。我们总说改革进步,但真正的改革往往不是自上而下,而是自下而上。如果没有Guava,开源社区中就不会有很多优秀的库和组件。JDK会采纳这些优秀的建议吗?不知道,但至少JAVA一直在进步,希望它会越来越好。