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”, ...
随机推荐
- 000 Html基本标签与案例
在CSS之前,需要先介绍一下HTML的常用标签. 1.html与css的关系 2.程序 <!DOCTYPE HTML> <html> <head> <meta ...
- ionic获取ios唯一设备id的解决方案
经常有朋友来问这个问题. 每次都去解释这个问题也浪费不少时间, 所以还是开一篇文章, 把这个问题说清楚吧. 先纠正一个误区吧: 有同学可以通过ionic natvie的device插件获取. 我们在文 ...
- 001.LVM简介
一 概念 LVM是 Logical Volume Manager(逻辑卷管理)的简写,它由Heinz Mauelshagen在Linux 2.4内核上实现.LVM将一个或多个硬盘的分区在逻辑上集合,相 ...
- 使用ajax与jqplot的小体会
在使用ajax与jqplot时遇到了传值的问题!一开始都不知值是怎么传过去的,只找到了例子是以<div id="data">原始数据</div>这样子来接收 ...
- Redis高可用之集群配置(六)
0.Redis目录结构 1)Redis介绍及部署在CentOS7上(一) 2)Redis指令与数据结构(二) 3)Redis客户端连接以及持久化数据(三) 4)Redis高可用之主从复制实践(四) 5 ...
- Java HashMap 分析四篇连载
Java的HashMap非常的常用,本篇研究它的实现算法,最后希望计算出内存占用,性能的量化数据,然后得出什么时候使用HashMap,什么时候不能滥用的结论. HashMap实际上是一个数组,数组里 ...
- 解决apache上访问 cgi脚本时总是在网页中显示出脚本的源代码而不是执行结果的问题
apache是支持cgi脚本的,但是需要保证四个条件: 1.放置cgi脚本的文件夹本身需要对apache服务器这个用户(一般默认用户名是www,linux下的用户机制请自行百度)开放x(即可执行)权限 ...
- Codeforces.1041F.Ray in the tube(思路)
题目链接 \(Description\) 有两条平行于\(x\)轴的直线\(A,B\),每条直线上的某些位置有传感器.你需要确定\(A,B\)轴上任意两个整点位置\(x_A,x_B\),使得一条光线沿 ...
- python3 开发面试题(面向对象)6.6
""" 封装.继承.多态 1. 谈谈你对面向对象的理解? 2. Python面向对象中的继承有什么特点? 3. 面向对象深度优先和广度优先是什么? 4. 面向对象中sup ...
- springmvc学习总结(一) -- 从零搭建,基础入门
1.新建maven项目 参考mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(上)第一部分,修改配置 2.修改pom.xml 文件 <proj ...