Chapter 5 -- ImmutableCollections
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的更多相关文章
- Modern C++ CHAPTER 2(读书笔记)
CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper
前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger
Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...
- [转]第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV
仅供参考,还未运行程序,理解部分有误,请参考英文原版. 绿色部分非文章内容,是个人理解. 转载请注明:http://blog.csdn.net/raby_gyl/article/details/174 ...
- 《深入理解计算机系统》 Chapter 7 读书笔记
<深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...
- 《Linux内核设计与实现》Chapter 3 读书笔记
<Linux内核设计与实现>Chapter 3 读书笔记 进程管理是所有操作系统的心脏所在. 一.进程 1.进程就是处于执行期的程序以及它所包含的资源的总称. 2.线程是在进程中活动的对象 ...
- PRML Chapter 2. Probability Distributions
PRML Chapter 2. Probability Distributions P68 conjugate priors In Bayesian probability theory, if th ...
- PRML Chapter 1. Introduction
PRML Chapter 1. Introduction 为了防止忘记,要把每章的重要内容都记下来,从第一章开始 2012@3@28 今天又回去稍微翻了一下第一章内容,发现第一次看的时候没有看透,每次 ...
- MathType 插入定义的chapter and section break后无法隐藏
每一章标题后面插入一个“Next Section Break”,这样定稿后各章文件组合为总文件后,方程编号会自动递增,如果已经插入了默认的“Equation Chapter 1 Section 1”, ...
随机推荐
- 006.FTP用户访问控制配置
一 FTP控制文件 1.1 文件说明 /etc/vsftpd/ftpusers:黑名单,优先级高 #通常不修改此文件 /etc/vsftpd/user_list:黑名单,优先级相对低 注意:Linux ...
- 《编写可维护的javascript》读书笔记(中)——编程实践
上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...
- Linux文件的所有权与权限
要了解Linux的权限,需要和Linux的用户与组的概念一并理解,不了解的同学请参考Linux的用户和组 简介 在Linux中,每个文件除了有用户和组的信息以外,还有其对应的权限.可使用来查看. [r ...
- 多线程学习笔记八之线程池ThreadPoolExecutor实现分析
目录 简介 继承结构 实现分析 ThreadPoolExecutor类属性 线程池状态 构造方法 execute(Runnable command) addWorker(Runnable firstT ...
- 异常日志框架Exceptionless结合.NET Core(本地部署)
一.前言 1.分布式异常日志收集框架Exceptionless是开源的工具,根据官方给出的说明: Exceptionless可以为您的ASP.NET.Web API.WebFrm.WPF.控制台和MV ...
- android activity 启动模式
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 1,标准的, 2,单个 顶部 3,单个 任务 4,单个 实例 标准的 就是 每启动一次这 ...
- BZOJ.1031.[JSOI2007]字符加密(后缀数组)
题目链接 环可以拆成链:对字符串排序能想到后缀数组. 完了.输出时忽略长度不足n的串,输出s[sa[i]+n-1],即排名为i的字符串的末尾. //4140kb 744ms #include < ...
- hiho1269 优化延迟 ([Offer收割]编程练习赛1)
一道中文题,就不用翻译了. 大意是讲,一串数字,可以按照输入的先后顺序扔到一个固定大小的缓冲池子里,这个池子里的数输出顺序随意.然后计算—— SP=1*Pi1+2*Pi2+3*Pi3+...+N*Pi ...
- tkinter的GUI设计:界面与逻辑分离(四)-- 与 matplotlib 结合
有些场合,我们需要对数据可视化.单是靠 tkinter 难度太大,而且做出来的效果不一定理想. 此时,将 tkinter 与 matplotlib 结合,是最好的选择. 知识点: 将 tkinter ...
- Codeforces Round #394 (Div. 2) A. Dasha and Stairs 水题
A. Dasha and Stairs 题目连接: http://codeforces.com/contest/761/problem/A Description On her way to prog ...