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”, ...
随机推荐
- Codeforces Round #529 (Div. 3) 题解
生病康复中,心情很不好,下午回苏州. 刷了一套题散散心,Div 3,全部是 1 A,感觉比以前慢了好多好多啊. 这几天也整理了一下自己要做的事情,工作上要努力... ... 晚上还是要认认真真背英语的 ...
- 【Ray Tracing in One Weekend 超详解】 光线追踪1-6
新的一年,前来打卡 Preface 回顾上一篇,我们讲述了漫反射材质,也就是平时的磨砂表面. 它一种将入射光经表面随机散射形成的材质,是一种非常普遍的表面形式. 这一篇,我们将来学习镜面反射,或者说是 ...
- View的工作原理(一) 总览View的工作流程
View的工作原理(一) 总览View的工作流程 学习自 <Android开发艺术探索> 简书博主-丶蓝天白云梦 Overview 从本章开始,开始学习View的工作原理,包括View的 ...
- Linux学习路线+资源
Linux学习路线,个人收集分享 学习路线图 资源链接(蓝色下划线字体对应相应资源链接) Linux 基础 Linux 基础 Linux安装专题教程 Linux中文环境 Linux—从菜鸟到高手 鸟哥 ...
- leetcode 岛屿的个数 python
岛屿的个数 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包 ...
- 【WIN10】Segoe MDL2 Assets
APP下載地址:https://www.microsoft.com/store/apps/9nblggh5k2hf 最近使用文本圖標Segoe MDL2 Assets時,使用字符映射表看,那個圖標真的 ...
- 媒体查询@media query
@media query 媒体查询 @media (min-width:768px)小屏 (>=) @media (min-width:992px)中屏 @media (min-width:12 ...
- java读取记事本文件第一个字符遇到的一个坑
记事本数据是这样的: Faq_faqTitle=常见问题_标题Faq_faqKeyword=关键字Faq_faqDescription=FAQ描述...... 文件编码:utf-8有签名 然后用jav ...
- java之ibatis数据缓存
使用IBatis作数据缓存 1.SqlMapConfig.xml中<settingscacheModelsEnabled="true" //设置为trueenhancemen ...
- ThinkPHP 模型方法 getField() 和 select() 使用技巧
getField() 使用技巧 getField() 方法是 ThinkPHP 中用来获取字段值的方法,区别于 select() 和 find() 方法,通常仅用于获取个别字段的值.但是事实上并没有那 ...