欢迎关注Hadoop、Spark、Flink、Hive、Hbase、Flume等大数据资料分享微信公共账号:iteblog_hadoop
  1. 文章总数:978
  2. 浏览总数:11,966,451
  3. 评论:3937
  4. 分类目录:106 个
  5. 注册用户数:6126
  6. 最后更新:2018年12月15日
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
iteblog_hadoop
大数据技术博客公众号bigdata_ai
大数据猿:
bigdata_ai

Guava学习之Immutable集合

  Immutable中文意思就是不可变。那为什么需要构建一个不可变的对象?原因有以下几点:

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

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

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")时,运行代码将会出现以下异常:

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,会发生什么情况?在上述代码的下面加入以下代码:

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

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

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

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

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

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

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来实现:

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不可变集合
CollectionJDKImmutableCollection
ListJDKImmutableList
SetJDKImmutableSet
SortedSet/NavigableSetJDKImmutableSortedSet
MapJDKImmutableMap
SortedMapJDKImmutableSortedMap
MultisetGuavaImmutableMultiset
SortedMultisetGuavaImmutableSortedMultiset
MultimapGuavaImmutableMultimap
ListMultimapGuavaImmutableListMultimap
SetMultimapGuavaImmutableSetMultimap
BiMapGuavaImmutableBiMap
ClassToInstanceMapGuavaImmutableClassToInstanceMap
TableGuavaImmutableTable
本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【Guava学习之Immutable集合】(https://www.iteblog.com/archives/524.html)
喜欢 (7)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!