Guava学习之Immutable集合

转载 2013年12月06日 11:19:47
Immutable中文意思就是不可变。那为什么需要构建一个不可变的对象?原因有以下几点:

  1. 在并发程序中,使用Immutable既保证线程安全性,也大大增强了并发时的效率(跟并发锁方式相比)。尤其当一个对象是值对象时,更应该考虑采用Immutable方式;
  2. 被不可信的类库使用时会很安全;
  3. 如果一个对象不需要支持修改操作(mutation),将会节省空间和时间的开销;经过分析,所有不可变的集合实现都比可变集合更加有效地利用内存;
  4. 可以当作一个常量来对待,并且这个对象在以后也不会被改变。

  将一个对象复制一份成immutable的,是一个防御性编程技术。在JDK类库中很多集合(List、Set、Map等)都可以调用Collections类提供的静态方法unmodifiableXXX(…)来得到一个不可修改的视图,如下所示:

1
2
3
4
5
6
7
List list = new ArrayList();
list.add("wyp");
list.add("good");
 
List unmodifiableList = Collections.unmodifiableList(list);
System.out.println(unmodifiableList);//[wyp, good]
unmodifiableList.add("add");

上述代码利用Collections.unmodifiableList(list)得到一个不可修改的集合unmodifiableList,当unmodifiableList.add(“add”)时,运行代码将会出现以下异常:

1
2
3
4
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.Collections$UnmodifiableCollection.add(Collections.java:1018)
    at com.wyp.test.testFiles(test.java:152)
    at com.wyp.test.main(test.java:160)

一切看起来很不错,因为调用unmodifiableList.add()会抛出一个java.lang.UnsupportedOperationException。但,如果有用户修改了list,会发生什么情况?在上述代码的下面加入以下代码:

1
2
list.add("add");
System.out.println(unmodifiableList);

当你再次打印unmodifiableList的时候,你会发现结果是[wyp, good, add],多了一个add元素。unmodifiableList不是不可变的吗?这显然不是我们期望的。

说明:Collections.unmodifiableList(…)实现的不是真正的不可变集合,当原始集合被修改后,不可变集合里面的元素也是跟着发生变化。

利用JDK类库中提供的unmodifiableXXX方法最少存在以下几点不足:

  1. 笨拙:因为你每次都得写那么多代码;
  2. 不安全:如果没有引用到原来的集合,这种情况之下才会返回唯一真正永恒不变的集合;
  3. 效率很低:返回的不可修改的集合数据结构仍然具有可变集合的所有开销。

Guava类库中提供的Immutable才是真正的不可修改的集合。

1
2
3
import com.google.common.collect.ImmutableList;
 
ImmutableList immutableList = ImmutableList.of("wyp", "good");

当你往immutableList 中添加元素,也会抛出java.lang.UnsupportedOperationException异常。可以用ImmutableList提供的以下几个方法来得到一个不可变的集合:
copyOf(Collection<? extends E> elements)比如ImmutableList.copyOf(list);
用of()方法得到一个空的不可变的List(ImmutableList提供了很多of()的重写);
利用Builder来实现:

1
2
3
4
5
List list = new ArrayList();
list.add("wyp");
list.add("good");
ImmutableList GOOGLE_IMMUTABLE = ImmutableList
                . builder().addAll(list).add("add").build();

JDK和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集合

Immutable中文意思就是不可变。那为什么需要构建一个不可变的对象?原因有以下几点:在并发程序中,使用Immutable既保证线程安全性,也大大增强了并发时的效率(跟并发锁方式相比)。尤其当一个对...
  • w397090770
  • w397090770
  • 2013年07月12日 16:00
  • 3686

Guava学习笔记【6】:Immutable(不可变)集合

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:   ...
  • azhegps
  • azhegps
  • 2017年05月08日 23:56
  • 73

Google的guava,Java中集合的增强工具

1-使用 GOOGLE COLLECTIONS,GUAVA,STATIC IMPORTS 编写漂亮代码 写在前面:  以前在一个项目中用到过guava,当时匆匆用,也没细研究,今天偶然在o...
  • he90227
  • he90227
  • 2015年01月12日 15:19
  • 2098

《Guava学习笔记之一》:不可变集合Immutable

《Guava学习笔记之一》:不可变集合ImmutableGuava,简单来说,就是一些类库,来简化我们常用的一些操作的实现。在学习Guava之前,先看一个场景。这样可以让我们先对这样一个类库有一个感性...
  • u010412719
  • u010412719
  • 2016年10月27日 21:44
  • 389

Guava学习笔记:Immutable(不可变)集合

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:   ...
  • crazzy0727
  • crazzy0727
  • 2014年09月23日 10:41
  • 377

Guava学习笔记:Immutable(不可变)集合

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠...
  • dyllove98
  • dyllove98
  • 2013年07月04日 21:16
  • 3552

Google-Guava学习:新集合类型

Multiset 可以用两种方式看待Multiset: 没有元素顺序限制的ArrayList Map,键为元素,值为计数 package com.cyq.newcollec...
  • cuiyaoqiang
  • cuiyaoqiang
  • 2017年01月12日 11:02
  • 460

Guava学习笔记:Immutable(不可变)集合

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:     1....
  • mingtianhaiyouwo
  • mingtianhaiyouwo
  • 2017年01月03日 20:13
  • 241

Google Guava集合在实体类中的应用示例

将实体list,转换成map,拿到所有id的集合方法。减少访问数据库。   实体基类BaseEntity package com.mytest; import org.apache.c...
  • z69183787
  • z69183787
  • 2016年11月25日 16:38
  • 680

Google Guava有用的几个集合类

、 Preconditions,前置条件判断 没有额外参数:抛出的异常中没有错误消息;有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;...
  • shangruo
  • shangruo
  • 2016年09月30日 16:50
  • 1307
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Guava学习之Immutable集合
举报原因:
原因补充:

(最多只允许输入30个字)