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”, ...
随机推荐
- vim/sed/awk/grep等文件批处理总结
Vim相关操作 1.基础 * 和 # 对对当前光标所在的单词进行搜索 %匹配括号移动,包括 (, {, [ K 查看man手册 ga 查看ascii值 g CTRL-G 统计字数,使用Visual模式 ...
- 洛谷P2261 [CQOI2007] 余数求和 [数论分块]
题目传送门 余数求和 题目背景 数学题,无背景 题目描述 给出正整数n和k,计算G(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod ...
- JdbcTemplate使用小结
org.springframework.jdbc.core.JdbcTemplate.query(String sql, Object[] args, RowMapper<StaffUnionV ...
- 手动搭建ABP2.1.3——基础框架
一.基础层搭建 1,创建一个空解决方案 2,层结构 Demo.Core[v:4.6.1]:类库 Demo.EntityFramework[v:4.6.1]:类库(引用Demo.Core) Demo.A ...
- 我的php.ini上传文件配置
可以通过phpinfo查看.当前的配置信息 # php -i | grep php.ini //查看php.ini位置 file_uploads = on ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C. Ray Tracing 数学
C. Ray Tracing 题目连接: http://codeforces.com/contest/724/problem/C Description oThere are k sensors lo ...
- java并发基础(三)--- 任务执行
第6章开始是第二部分,讲解结构化并发应用程序,大多数并发应用程序都是围绕“任务执行”构造的,任务通常是一些抽象的且离散的工作单元. 一.线程池 大多数服务器应用程序都提供了一种自然的任务边界:以独立的 ...
- linearLayout 和 relativeLayout的属性区别(转)
LinearLayout和RelativeLayout 共有属性:java代码中通过btn1关联次控件android:id="@+id/btn1" 控件宽度android:layo ...
- HDU 4786 Fibonacci Tree (2013成都1006题)
Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- UVA 11732 - strcmp() Anyone?(Trie)
UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比較,须要比較的总次数(注意.假设一个字符同样.实际上要还要和'\0'比一次,相当比2次) 思路:建T ...