Example

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

Why?

Immutable objects have many advantages, including:

不可变对象有很多优势,包括:

  • Safe for use by untrusted libraries.
  • 可被不可信任库安全使用
  • Thread-safe: can be used by many threads with no risk of race conditions.
  • 线程安全: 可被多线程使用却没有竞争的危险
  • Doesn't need to support mutation, and can make time and space savings with that assumption. All immutable collection implementations are more memory-efficient than their mutable siblings (analysis)
  • 不需要支持变化操作,这种设定下可以节省时间和空间. 所有不可变集合的实现相对于可变集合的同类在内存上更有效率
  • Can be used as a constant, with the expectation that it will remain fixed
  • 可被作为constant使用, 可变操作将抛出异常

Making immutable copies of objects is a good defensive programming technique. Guava provides simple, easy-to-use immutable versions of each standard Collection type, including Guava's own Collection variations.

使用对象的不可变copy是一种很好的防御性编程技术.Guava提供了简单易用的每种标准集合的不可变版本, 也包括一些Guava自己的集合变种.

The JDK provides Collections.unmodifiableXXX methods, but in our opinion, these can be

JDK提供Collections.unmodifiableXXX 方法, 但我们的观点是:

  • unwieldy and verbose; unpleasant to use everywhere you want to make defensive copies
  • 笨重冗长; 每个你想使用防御性copy的地方都会用得很不爽
  • unsafe: the returned collections are only truly immutable if nobody holds a reference to the original collection
  • 不安全: 返回的集合只有在没人持有原始集合的引用时才是真正的不可变
  • inefficient: the data structures still have all the overhead of mutable collections, including concurrent modification checks, extra space in hash tables, etc.
  • 效率低: 这种数据结构依然有所有的可变集合开销, 包括同步修改检查, 额外的hash表空间.

When you don't expect to modify a collection, or expect a collection to remain constant, it's a good practice to defensively copy it into an immutable collection.

当你不想修改一个集合,或者想要一个常量集合,把他复制到一个immutable collection是一个很好的做法

Important: Each of the Guava immutable collection implementations rejects null values. We did an exhaustive study on Google's internal code base that indicated that null elements were allowed in collections about 5% of the time, and the other 95% of cases were best served by failing fast on nulls. If you need to use null values, consider using Collections.unmodifiableList and its friends on a collection implementation that permits null. More detailed suggestions can be found here.

重点: 每个Guava不可变集合实现都排斥null值.我们在google的internal code base做了一次全力的代码调查, 发现集合中只有5%的时候存在null, 另外95%的时候最后都是应该使用快速失败来替代null.加入你需要使用null,考虑使用Collections.unmodifiableList和他那些可以允许null的朋友们.

How?

An ImmutableXXX collection can be created in several ways:

一个不可变XXX集合可以由如下几种方式创建:

    • using the copyOf method, for example, ImmutableSet.copyOf(set)
    • 使用copyOf方法, 例如, ImmutableSet.copyOf(set)
    • using the of method, for example, ImmutableSet.of("a", "b", "c") or ImmutableMap.of("a", 1, "b", 2)
    • 使用of方法,例如, ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)
    • using a Builder, for example,
    • 使用一个Builder, 例如:
public static final ImmutableSet<Color> GOOGLE_COLORS =
       ImmutableSet.<Color>builder()
           .addAll(WEBSAFE_COLORS)
           .add(newColor(0,191,255))
           .build();

Except for sorted collections, order is preserved from construction time. For example,

除了排序集合, 顺序在创建集合的时候是被保留的.例如

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

will iterate over its elements in the order "a", "b", "c", "d".

遍历时它的顺序是a, b, c, d

copyOf is smarter than you think

copyOf比你想象的更聪明

It is useful to remember that ImmutableXXX.copyOf attempts to avoid copying the data when it is safe to do so -- the exact details are unspecified, but the implementation is typically "smart". For example,

记住ImmutableXXX.copyOf在保证安全的情况下会尽量避免复制原始数据是很有用的 -- 精确的细节没有指定, 但是它的实现是很聪明的,例如:

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

In this code, ImmutableList.copyOf(foobar) will be smart enough to just return foobar.asList(), which is a constant-time view of the ImmutableSet.

这段代码, ImmutableList.copyOf(foobar)仅仅会聪明的返回foobar.asList(), 一个ImmutableSet的常量时间复杂度的方法

As a general heuristic, ImmutableXXX.copyOf(ImmutableCollection) tries to avoid a linear-time copy if

作为一个一般式启发, ImmutableXXX.copyOf(ImmutableCollection)在如下情况下会尝试避免线性时间的复制

  • it's possible using the underlying data structures in constant time. For example, ImmutableSet.copyOf(ImmutableList) can't be done in constant time.
  • 在常量时间内使用基础的数据结构是有可能的.例如, ImmutableSet.copyOf(ImmutableList)是不能在常量时间内完成的.
  • it wouldn't cause memory leaks -- for example, if you have ImmutableList<String> hugeList, and you doImmutableList.copyOf(hugeList.subList(0, 10)), an explicit copy is performed, so as to avoid accidentally holding on to references inhugeList that aren't needed.
  • 他不会造成内存泄露 -- 例如, 加入你有一个ImmutableList<String>的hugeList,并且你使用ImmutableList.copyOf(hugeList.subList(0, 10)), 执行一个明确的copy操作来避免意外持有hugeList的引用时不必要的
  • it won't change semantics -- so ImmutableSet.copyOf(myImmutableSortedSet) will perform an explicit copy, because the hashCode() andequals used by ImmutableSet have different semantics from the comparator-based behavior of ImmutableSortedSet.
  • 他不会改变语义 -- 所以 ImmutableSet.copyOf(myImmutableSortedSet)会执行一个显式的复制, 因为hashCode()和equals被ImmutableSet使用和给予比较器的ImmutableSortedSet会有不一样的语义

This helps minimize the performance overhead of good defensive programming style.

这帮助了最小化好的防御型编程的性能开销

asList

All immutable collections provide an ImmutableList view via asList(), so -- for example -- even if you have data stored as an ImmutableSortedSet, you can get the kth smallest element with sortedSet.asList().get(k).

所有不可变集合通过asList()方法提供了一个ImmutableList, -- 例如 -- 即使你在ImmutableSortedSet里保存了数据,你也可以使用sortedSet.asList().get(k)来获取第k小的元素

The returned ImmutableList is frequently -- not always, but frequently -- a constant-overhead view, rather than an explicit copy. That said, it's often smarter than your average List -- for example, it'll use the efficient contains methods of the backing collection.

返回的ImmutableList经常 -- 不是总是, 但经常是 -- 一个常量开销的视图, 而不是一个显式的复制.即便如此, 他也比一般的list要聪明 -- 例如, 他总是使用有效率的contains方法.

Details

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

对聪明的方法ImmutableList.copyOf(Collections)的解析

    /**
* Returns an immutable list containing the given elements, in order.
* 返回一个包含给定元素的有序不可变list
*
* <p>Despite the method name, this method attempts to avoid actually copying
* the data when it is safe to do so. The exact circumstances under which a
* copy will or will not be performed are undocumented and subject to change.
*
* 除开方法名不说, 这个方法在安全的时候尝试避免真正的拷贝数据.具体的情况是是否会真正复制是说不准的
* 有可能会不同情况而改变
*
* <p>Note that if {@code list} is a {@code List<String>}, then {@code
* ImmutableList.copyOf(list)} returns an {@code ImmutableList<String>}
* containing each of the strings in {@code list}, while
* ImmutableList.of(list)} returns an {@code ImmutableList<List<String>>}
* containing one element (the given list itself).
*
* 注意如果list是一个List<String>,那么ImmutableList.copyOf(list)返回一个
* 包含list所有元素的ImmutableList<String>, 而ImmutableList.of(list)则会返回一个
* 只有一个元素(list本身)的ImmutableList<List<String>>
*
* <p>This method is safe to use even when {@code elements} is a synchronized
* or concurrent collection that is currently being modified by another
* thread.
*
* 这个方法即使在和正在被修改的同步集合或并发集合一起使用也是安全的
*
* @throws NullPointerException if any of {@code elements} is null
*/
public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
// 对于不可变集合直接使用asList()来返回他的不可变副本,asList并不会真的复制
// elements这个集合, 而是返回一个代理elements集合的集合
if (elements instanceof ImmutableCollection) {
@SuppressWarnings("unchecked") // all supported methods are covariant
ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
return list.isPartialView() ? copyFromCollection(list) : list;
}
return copyFromCollection(elements);
}

asList()方法

  public ImmutableList<E> asList() {
ImmutableList<E> list = asList;
return (list == null) ? (asList = createAsList()) : list;
}

-->
ImmutableList<E> createAsList() {
switch (size()) {
case 0:
return ImmutableList.of();
case 1:
return ImmutableList.of(iterator().next());
default:
return new RegularImmutableAsList<E>(this, toArray());
}
} -->
RegularImmutableAsList(ImmutableCollection<E> delegate, Object[] array) {
this(delegate, ImmutableList.<E>asImmutableList(array));
}

Chapter 5 -- ImmutableCollections的更多相关文章

  1. Modern C++ CHAPTER 2(读书笔记)

    CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...

  2. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper

    前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...

  3. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger

    Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...

  4. [转]第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV

    仅供参考,还未运行程序,理解部分有误,请参考英文原版. 绿色部分非文章内容,是个人理解. 转载请注明:http://blog.csdn.net/raby_gyl/article/details/174 ...

  5. 《深入理解计算机系统》 Chapter 7 读书笔记

    <深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...

  6. 《Linux内核设计与实现》Chapter 3 读书笔记

    <Linux内核设计与实现>Chapter 3 读书笔记 进程管理是所有操作系统的心脏所在. 一.进程 1.进程就是处于执行期的程序以及它所包含的资源的总称. 2.线程是在进程中活动的对象 ...

  7. PRML Chapter 2. Probability Distributions

    PRML Chapter 2. Probability Distributions P68 conjugate priors In Bayesian probability theory, if th ...

  8. PRML Chapter 1. Introduction

    PRML Chapter 1. Introduction 为了防止忘记,要把每章的重要内容都记下来,从第一章开始 2012@3@28 今天又回去稍微翻了一下第一章内容,发现第一次看的时候没有看透,每次 ...

  9. MathType 插入定义的chapter and section break后无法隐藏

    每一章标题后面插入一个“Next Section Break”,这样定稿后各章文件组合为总文件后,方程编号会自动递增,如果已经插入了默认的“Equation Chapter 1 Section 1”, ...

随机推荐

  1. windows下mysql配置

    windows下mysql配置   忙活了大半天,总算配置好了,本文献给windows下没试用过Mysql的小白,勿喷 http://blog.csdn.net/z1074907546/article ...

  2. JSP中的指令概述和示例

    一.JSP——Java server page :java服务端的页面,这是属于一个后端技术 1.前端技术: html.css.javascript 2.后端技术: java语言.框架(mybatis ...

  3. Qt界面UI之QML初见(学习笔记四)

    拖了大半年,今天终于有更新了...我自己都不好意思,最近太忙了! 今天讲一下:QML语法 一 概述 QML是一种专门用于构建用户界面的编程语言,它允许用户构建高性能,具有流畅特效的可视化应用程序,QM ...

  4. Java变量的默认值和初始化

    Java变量的默认值和初始化 学习自 <Thinking In Java> 技术小黑屋-为什么局部变量需要显式设置初始化值 变量的默认值 注意只有成员变量才有默认值,而局部变量必须要赋初值 ...

  5. Codeforces.1027F.Session in BSU(思路 并查集)

    题目链接 \(Description\) 有\(n\)个人都要参加考试,每个人可以在\(ai\)或\(bi\)天考试,同一天不能有两个人考试.求最晚考试的人的时间最早能是多少.无解输出-1. \(So ...

  6. Windows 7 MBR的修复与Linux产品正确卸载

    这几天折腾系统很令人崩溃,但也明白了开机引导流程具体如何. 觉得Centos 7不好用,想卸载Redhat安装Ubuntu,为了图方便直接把红帽的硬盘区格式化了.于是开机引导崩溃,咨询了下大神,大神叫 ...

  7. bash编程之xargs实用技巧

    xargs结合管道操作符|,可以完成很多看似复杂的问题: 1.快速删除所有.log日志文件 机器运行久了,就会有各式各样的日志文件,散落在各个目录下,可以利用下面的方法: find ./ -name ...

  8. 两个div如何并列 (转)

    两个div如何并列?当用到div+css代替table时,我习惯用两个方法: 1 <div id="parent"> <div id="child_1& ...

  9. STM32F4 External interrupts

    STM32F4 External interrupts Each STM32F4 device has 23 external interrupt or event sources. They are ...

  10. 《Linux设备驱动开发详解(第3版)》(即《Linux设备驱动开发详解:基于最新的Linux 4.0内核》)--宋宝华

    http://blog.csdn.net/21cnbao/article/details/45322629