Immutable(不可变)集合

一、概述

guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开。Collections是jdk提供的一个工具类。

Guava中不可变对象和Collections工具类的unmodifiableSet/List/Map/etc的区别:

当Collections创建的不可变集合的wrapper类改变的时候,不可变集合也会改变,而Guava的Immutable集合保证确实是不可变的。

1、JDK中实现immutable集合

在JDK中提供了Collections.unmodifiableXXX系列方法来实现不可变集合, 但是存在一些问题,下面我们先看一个具体实例:

public class ImmutableTest {

    @Test
public void testJDKImmutable(){
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c"); //通过list创建一个不可变的unmodifiableList集合
List<String> unmodifiableList=Collections.unmodifiableList(list);
System.out.println(unmodifiableList); //通过list添加元素
list.add("ddd");
System.out.println("往list添加一个元素:"+list);
System.out.println("通过list添加元素之后的unmodifiableList:"+unmodifiableList); //通过unmodifiableList添加元素
unmodifiableList.add("eee");
System.out.println("往unmodifiableList添加一个元素:"+unmodifiableList); }
}

运行结果:

通过运行结果我们可以看出:虽然unmodifiableList不可以直接添加元素,但是我的list是可以添加元素的,而list的改变也会使unmodifiableList改变。

所以说Collections.unmodifiableList实现的不是真正的不可变集合。

2、Guava的immutable集合

Guava提供了对JDK里标准集合类里的immutable版本的简单方便的实现,以及Guava自己的一些专门集合类的immutable实现。当你不希望修改一个集合类,

或者想做一个常量集合类的时候,使用immutable集合类就是一个最佳的编程实践。

注意:每个Guava immutable集合类的实现都拒绝null值。我们做过对Google内部代码的全面的调查,并且发现只有5%的情况下集合类允许null值,而95%的情况下

都拒绝null值。万一你真的需要能接受null值的集合类,你可以考虑用Collections.unmodifiableXXX。

immutable集合可以有以下几种方式来创建:

  1、用copyOf方法, 譬如, ImmutableSet.copyOf(set)

  2、使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)

  3、使用Builder类

举例:

 @Test
public void testGuavaImmutable(){ List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c"); ImmutableList<String> imlist=ImmutableList.copyOf(list);
System.out.println("imlist:"+imlist); ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry");
System.out.println("imOflist:"+imOflist); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b");
System.out.println("imSortList:"+imSortList); list.add("baby");
//关键看这里是否imlist也添加新元素了
System.out.println("list添加新元素之后看imlist:"+imlist); ImmutableSet<Color> imColorSet =
ImmutableSet.<Color>builder()
.add(new Color(0, 255, 255))
.add(new Color(0, 191, 255))
.build(); System.out.println("imColorSet:"+imColorSet);
}

运行结果:发现imlist并未改变。

对于排序的集合来说有例外,因为元素的顺序在构建集合的时候就被固定下来了。譬如,ImmutableSet.of("a", "b", "c", "a", "d", "b"),对于这个集合的遍历顺序来说就是"a", "b", "c", "d"。

更智能的copyOf

copyOf方法比你想象的要智能,ImmutableXXX.copyOf会在合适的情况下避免拷贝元素的操作-先忽略具体的细节,但是它的实现一般都是很“智能”的。譬如:

  @Test
public void testCotyOf(){
ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa");
System.out.println("imSet:"+imSet); //set直接转list
ImmutableList<String> imlist=ImmutableList.copyOf(imSet);
System.out.println("imlist:"+imlist); //list直接转SortedSet
ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet);
System.out.println("imSortSet:"+imSortSet); List<String> list=new ArrayList<String>();
for(int i=0;i<=10;i++){
list.add(i+"x");
}
System.out.println("list:"+list); //截取集合部分元素
ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 8));
System.out.println("imInfolist:"+imInfolist);
}

运行结果

Guava集合和不可变对应关系

可变集合类型 可变集合源:JDK or Guava? Guava不可变集合
Collection JDK ImmutableCollection
List JDK ImmutableList
Set JDK ImmutableSet
SortedSet/NavigableSet JDK ImmutableSortedSet
Map JDK ImmutableMap
SortedMap JDK ImmutableSortedMap
Multiset Guava ImmutableMultiset
SortedMultiset Guava ImmutableSortedMultiset
Multimap Guava ImmutableMultimap
ListMultimap Guava ImmutableListMultimap
SetMultimap Guava ImmutableSetMultimap
BiMap Guava ImmutableBiMap
ClassToInstanceMap Guava ImmutableClassToInstanceMap
Table Guava ImmutableTable

本文参考:Guava学习笔记:Immutable(不可变)集合 感谢!

 想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。中校【12】

java代码之美(4)---guava之Immutable(不可变)集合的更多相关文章

  1. java代码(4)---guava之Immutable(不可变)集合

    Immutable(不可变)集合   一,概述 guava是google的一个库,弥补了java语音的很多方面的不足,很多在java8中已有实现,暂时不展开,Collections是jdk提供的一个工 ...

  2. java代码之美(14)---Java8 函数式接口

    Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加 ...

  3. java代码之美(15)---Java8 Function、Consumer、Supplier

    Java8 Function.Consumer.Supplier 有关JDK8新特性之前写了三篇博客: 1.java代码之美(1)---Java8 Lambda 2.java代码之美(2)---Jav ...

  4. Guava集合--Immutable(不可变)集合

    所谓不可变集合,顾名思义就是定义了之后不可修改的集合. 一.为什么要使用不可变集合 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态 ...

  5. Immutable(不可变)集合

    Immutable(不可变)集合 不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对 ...

  6. java代码之美(3)---guava 复写Object常用方法

    guava 复写Object常用方法 Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方 ...

  7. java代码之美(5)---guava之Multiset

    guava之Multiset 一.概述 Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关.Multiset继承于JDK的Cllection接口,而不是Set接 ...

  8. java代码之美(11)---java代码的优化

    java代码的优化 随着自己做开发时间的增长,越来越理解雷布斯说的: 敲代码要像写诗一样美.也能理解有一次面试官问我你对代码有洁癖吗? 一段好的代码会让人看就像诗一样,也像一个干净房间会让人看去很舒服 ...

  9. java代码(3)----guava复写Object常用方法

    guava复写Object常用方法 Guava是一个Google的基于java1.6的类库集合的扩展项目,这个库提供用于集合,缓存,支持原语,并发性,字符串处理,I/O和验证的实用方法, 这些高质量的 ...

随机推荐

  1. Excel—文本函数

    LEFT(从左开始取文本的函数)就是这个函数可以帮我们取文本,按照从左到右的顺序取 函数语法:=LEFT(要取的文本所在的单元格,从左到右取前几位)这表示的是字符,一个英文字母占一个字符,一个汉子也占 ...

  2. Istio 是什么?

    使用云平台可以为组织提供丰富的好处.然而,不可否认的是,采用云可能会给 DevOps 团队带来压力.开发人员必须使用微服务以满足应用的可移植性,同时运营商管理了极其庞大的混合和多云部署.Istio 允 ...

  3. myBase Desktop 6.5.1 无限期试用

    清空安装目录下的"nyfedit.ini"文件的"App.UserLic.FirstUseOn="配置项的值

  4. JIRA

    https://www.jianshu.com/p/8c14b52ce692 JIRA这个工具接触有好几年了,在多个海外项目上都用过这个工具.去年又在项目上深度使用后就有点爱不释手了,回国后也在找机会 ...

  5. [R]R语言的module工程化

    很遗憾,这还是一个挖坑的问题,解决方案并不是很确定. 需求是,大多数的语言都提供import包或module的功能,避免全部代码写到一个文件中,方便管理与维护. 如常用的database模块,每次写R ...

  6. wamp apache 设置多端口

  7. 面试题int和Integer

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...

  8. C# 中传参中的OUT 和 ref 区别 笔记

    //out传参前需要对参数进行赋值处理,ref则不需要.//out.ref 传参都可以对值进行改变 1 static void Main(string[] args) { ; //int J = 10 ...

  9. 安装xlwt和xlrd

    因为想用python实现读写excel.百度了下,要安装xlwt和xlrd,网上各种方法,很多都不便利.最后利用pip安装很方便. 第一步:浏览器检索“xlwt安装”,点击第一个网页(百度) 即出现如 ...

  10. ProgressBar三种style

    一.普通的ProgressBar显示如图 <ProgressBar        android:id="@+id/pbNormal"        android:layo ...