我的技术博客经常被流氓网站恶意爬取转载。请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版、有效的链接、正确的代码缩进、更好的阅读体验。

例子

public static final ImmutableSet<String> COLOR_NAMES =ImmutableSet.of(
"red",
"orange",
"yellow",
"green",
"blue",
"purple");
class Foo{
Set<Bar> bars;
Foo(Set<Bar> bars){
this.bars =ImmutableSet.copyOf(bars);// defensive copy!
}
}

为什么要用不可变集合?

不可变(Immutable)的对象有很多好处,包括:

  • 被不可靠的库使用的安全性
  • 线程安全:可以被多个线程同时使用,不会出现资源竞争(race condition)
  • 因不可变而带来时间、空间效率提升。所有的不可变集合实现都比相应的可变集合效率高。(分析)
  • 可以用作常量,可以信任它不会变

使用不可变的对象副本是一项典型的防御式编程技术。Guava为每种 Collection 类型提供了简单、易用的不可变版本,也包括Guava自己的 Collection 类型。

JDK 提供 Collections.unmodifiableXXX 方法,但在我们看来,这些方法的问题是:

  • 笨重而冗长;每处你想要得到保护性副本时都这样用,会令人不爽
  • 不安全:仅当没有人持有对原来集合对象的引用时,返回的集合才是真正不可变的
  • 低效:数据结构上仍然带有所有可变集合需要的开销,包括同步修改检查,hash表里的额外空间,等等。

当你不准备修改一个collection,或者希望它保持为常量,把它保护性拷贝为一个不可变collection是个很好的做法。

重要: Guava实现的每个不可变集合都不支持null值。我们对Google的内部代码库进行了详尽无遗的研究,发现只有5%的情况下集合里可以有 null 元素,而95%的情况下对null直接报错会更好。如果你需要支持null值,考虑用 Collections.unmodifiableList 和其他允许null的类似集合实现。更详细的建议请参见这里

怎么用?

创建 ImmutableXXX 集合可用以下几种方法:

    • 用 copyOf 方法,例如, ImmutableSet.copyOf(set)
    • 用 of 方法,例如, ImmutableSet.of("a", "b", "c") 或 ImmutableMap.of("a", 1, "b", 2)
    • 用 Builder,例如,
publicstaticfinalImmutableSet<Color> GOOGLE_COLORS =
ImmutableSet.<Color>builder()
.addAll(WEBSAFE_COLORS)
.add(newColor(0,191,255))
.build();

除了有序集合之外的集合,会保留创建时元素的顺序。例如,

ImmutableSet.of("a","b","c","a","d","b")

遍历元素的顺序会是 "a", "b", "c", "d"。

copyOf 比你想象的聪明

要记住 ImmutableXXX.copyOf 会尽量避免拷贝数据,只要这样是安全的——具体的实现细节不一,但总体来说是“聪明的”。例如,

ImmutableSet<String> foobar =ImmutableSet.of("foo","bar","baz");
thingamajig(foobar); void thingamajig(Collection<String> collection){
ImmutableList<String> defensiveCopy =ImmutableList.copyOf(collection);
...
}

在这段代码中,聪明的 ImmutableList.copyOf(foobar) 会直接返回 foobar.asList(),是这个 ImmutableSet 的常量时间复杂度的拷贝。

作为一般性的探索,ImmutableXXX.copyOf(ImmutableCollection) 会尽量避免线性时间复杂度的拷贝,如果

  • 基础数据结构可以在常量时间复杂度内使用。例如, ImmutableSet.copyOf(ImmutableList) 无法在常量时间内完成。
  • 不会引起内存泄漏——例如,如果有一个很大的 ImmutableList<String> hugeList ,然后执行 ImmutableList.copyOf(hugeList.subList(0, 10)),会进行显式的拷贝,为了避免无意中保持着对 hugeList 中不必要的元素的引用。
  • 不会改变语义 —— 所以,ImmutableSet.copyOf(myImmutableSortedSet) 会进行显式的拷贝,因为 ImmutableSet 使用的 hashCode() 和 equals 与依赖 comparator 的 ImmutableSortedSet 语义不同。

这帮助了良好的防御式编程减小性能开销。

asList

所有的不可变集合都提供了转化为 ImmutableList 的方法 asList()。因此——例如——即使你把数据存为 ImmutableSortedSet 格式,你也可以用 sortedSet.asList().get(k) 得到第k个最小元素。

返回的 ImmutableList 经常是——并不是每次,但是经常——一个常量时间得到的副本,而不是显式的靠别。也就是说,它一般比普通的 List 要聪明——例如,它会知道调用底层结构的更有效率的 contains 方法。

细节

Where?

Interface JDK or Guava? Immutable Version
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官方文档:GuavaExplained - ImmutableCollectionsExplained 译者:戴仓薯

[Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)的更多相关文章

  1. [Guava官方文档翻译] 1.Guava简介 (Introduction)

    用户指南 Guava包含Google在Java项目中用到的一些核心库:collections, caching, primitives support, concurrency 库, common a ...

  2. [Guava官方文档翻译] 5. Guava的Object公共方法 (Common Object Utilities Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537367.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  3. Java基础 @org.junit.Test-单元测试方法 + 操纵Collection和Map的工具类 : Collections 的sort/binarySearch/max/min等静态方法

      单元测试代码:  ( 在IDEA中先输入'@Test '然后根据提示进行自动修订即可!!运行时直接运行即可! 若有多个单元测试块的时候,直接把鼠标放在哪里就自动在哪里运行那个单元块) import ...

  4. [Guava官方文档翻译] 2.使用和避免使用null (Using And Avoiding Null Explained)

    本文地址:http://www.cnblogs.com/hamhog/p/3536647.html "null很恶心." -Doug Lea "这是一个令我追悔莫及的错误 ...

  5. .Net中的不可变集合(Immutable Collection)简介

    今天发现MS在Nuget上发布了一个Immutable Collection的程序集,提供了对不可变对象的集合的支持. 简单的看了一下,貌似支持的还比较全: ImmutableArray<T&g ...

  6. [Guava官方文档翻译] 4. 使用Guava Ordering排序 (Ordering Explained)

    本文地址:http://www.cnblogs.com/hamhog/p/3537233.html 示例 assertTrue(byLengthOrdering.reverse().isOrdered ...

  7. [Guava官方文档翻译] 6. 用Guava辅助Throwable异常处理 (Throwables Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537508.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  8. [Guava官方文档翻译] 3. 前置条件检查(Preconditions Explained)

    本文地址:http://www.cnblogs.com/hamhog/p/3536964.html 前置条件检查 Guava提供了一些检查前置条件的utilities.我们强烈建议静态import这些 ...

  9. Immutable(不可变)集合

    不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 对不可靠的客户代 ...

随机推荐

  1. Oracle 中 union与union all

    如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字. union(或称为联合)的作用是将多个结果合并在一起显示出来. union和uni ...

  2. C/C++语言中#的神奇作用:把宏参数字符串化/贴合宏参数

    宏中"#"和"##"的用法 一.一般用法   我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. #define STR(s)      #s # ...

  3. systemd service

    Man page systemd.unit SYSTEMD.UNIT(5) systemd.unit SYSTEMD.UNIT(5) NAME systemd.unit - Unit configur ...

  4. ThinkPHP CURD方法盘点:order方法

    order方法属于模型的连贯操作方法之一,用于对操作的结果排序. 用法 $Model->where('status=1')->order('id desc')->limit(5)-& ...

  5. 【jQuery插件】用jQuery Masonry快速构建一个pinterest网站布局(转)

    [jQuery插件]用jQuery Masonry快速构建一个pinterest网站布局 时间:2011年03月21日作者:愚人码头查看次数:29,744 views评论次数:25条评论 前段时间领导 ...

  6. hdu 1348 Wall(凸包模板题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    M ...

  7. javascript之css常用属性

    1. position : 属性值有absolute .fixed.relative absolute:生成绝对定位的元素,相对第一父元素进行定位: fixed :   生成绝对定位的元素,相对于浏览 ...

  8. C#获取指定网页源码的几种方法

    // WebClient private string GetWebClient(string url) { string strHTML = ""; WebClient myWe ...

  9. Maven学习小结(三 基本概念)

    1.Maven POM POM(Project Object Model)项目对象模型,是用Maven来管理项目里的一个叫做pom.xml的文件.所有的项目配置信息都被定义在这个文件中, 通过这个文件 ...

  10. 【Objective-C】4-空指针和野指针

    一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...