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. 使用Tornado异步接入第三方(支付宝)支付

    目前国内比较流行的第三方支付主要有支付宝和微信支付,博主最近研究了下如何用Python接入支付宝支付,这里我以Tornado作为web框架,接入支付宝构造支付接口. 使用Tornado异步接入支付宝支 ...

  2. Vue面试中,经常会被问到的面试题/Vue知识点整理

    一.对于MVVM的理解? MVVM 是 Model-View-ViewModel 的缩写.Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑.View 代表UI 组件,它负责将数 ...

  3. PBRT笔记(9)——贴图

    采样与抗锯齿 当高分辨率贴图被缩小时,贴图会出现严重的混淆现象.虽然第7章中的非均匀采样技术可以减少这种混叠的视觉影响,但是更好的解决方案是实现基于分辨率进行采样的纹理函数. 可以在使用贴图时先对贴图 ...

  4. BZOJ.4151.[AMPPZ2014]The Cave(结论)

    BZOJ 不是很懂他们为什么都要DFS三次.于是稳拿Rank1 qwq. (三道题两个Rank1一个Rank3效率是不是有点高qwq?) 记以\(1\)为根DFS时每个点的深度是\(dep_i\).对 ...

  5. 1062 Text Reverse

    http://acm.hdu.edu.cn/showproblem.php?pid=1062 思路: 最主要的是通过getline函数存取字符串. 如何读取单个单词,并且反向输出? 用\n作为单个单词 ...

  6. apache设置跨域请求

    <VirtualHost *:8888> DocumentRoot D:/xampp/htdocs/bss/ ServerName ims.drcloud.cn ErrorLog &quo ...

  7. BFS —— 信息学一本通(1451:棋盘游戏)

    题目描述 在一个4*4的棋盘上有8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的.移动棋子的规则是交换相邻两个棋子.现在给出一个初始棋盘和一个最终棋盘,要求你找出一个最短的移动序 ...

  8. python爬取网页内容demo

    #html文本提取 from bs4 import BeautifulSoup html_sample = '\ <html> \ <body> \ <h1 id = & ...

  9. vue 使用瞬间

    vue 使用瞬间 一, 图片类 <img :src="data.deptLogo | imgUrl" onerror="this.src='../img/headD ...

  10. python批量提取eml附件

    从批量eml文件中提取附件,使用方式如下 代码如下 import email import os import sys #获取eml附件信息 def Get_Annex_Message(FilePat ...