[Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)
我的技术博客经常被流氓网站恶意爬取转载。请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版、有效的链接、正确的代码缩进、更好的阅读体验。
例子
public static final ImmutableSet<String> COLOR_NAMES =ImmutableSet.of(
"red",
"orange",
"yellow",
"green",
"blue",
"purple");
class Foo{
Set<Bar> bars;
Foo(Set<Bar> bars){
this.bars =ImmutableSet.copyOf(bars);// defensive copy!
}
}
为什么要用不可变集合?
不可变(Immutable)的对象有很多好处,包括:
- 被不可靠的库使用的安全性
- 线程安全:可以被多个线程同时使用,不会出现资源竞争(race condition)
- 因不可变而带来时间、空间效率提升。所有的不可变集合实现都比相应的可变集合效率高。(分析)
- 可以用作常量,可以信任它不会变
使用不可变的对象副本是一项典型的防御式编程技术。Guava为每种 Collection 类型提供了简单、易用的不可变版本,也包括Guava自己的 Collection 类型。
JDK 提供 Collections.unmodifiableXXX 方法,但在我们看来,这些方法的问题是:
- 笨重而冗长;每处你想要得到保护性副本时都这样用,会令人不爽
- 不安全:仅当没有人持有对原来集合对象的引用时,返回的集合才是真正不可变的
- 低效:数据结构上仍然带有所有可变集合需要的开销,包括同步修改检查,hash表里的额外空间,等等。
当你不准备修改一个collection,或者希望它保持为常量,把它保护性拷贝为一个不可变collection是个很好的做法。
重要: Guava实现的每个不可变集合都不支持null值。我们对Google的内部代码库进行了详尽无遗的研究,发现只有5%的情况下集合里可以有 null 元素,而95%的情况下对null直接报错会更好。如果你需要支持null值,考虑用 Collections.unmodifiableList 和其他允许null的类似集合实现。更详细的建议请参见这里。
怎么用?
创建 ImmutableXXX 集合可用以下几种方法:
- 用 copyOf 方法,例如, ImmutableSet.copyOf(set)
- 用 of 方法,例如, ImmutableSet.of("a", "b", "c") 或 ImmutableMap.of("a", 1, "b", 2)
- 用 Builder,例如,
publicstaticfinalImmutableSet<Color> GOOGLE_COLORS =
ImmutableSet.<Color>builder()
.addAll(WEBSAFE_COLORS)
.add(newColor(0,191,255))
.build();
除了有序集合之外的集合,会保留创建时元素的顺序。例如,
ImmutableSet.of("a","b","c","a","d","b")
遍历元素的顺序会是 "a", "b", "c", "d"。
copyOf 比你想象的聪明
要记住 ImmutableXXX.copyOf 会尽量避免拷贝数据,只要这样是安全的——具体的实现细节不一,但总体来说是“聪明的”。例如,
ImmutableSet<String> foobar =ImmutableSet.of("foo","bar","baz");
thingamajig(foobar);
void thingamajig(Collection<String> collection){
ImmutableList<String> defensiveCopy =ImmutableList.copyOf(collection);
...
}
在这段代码中,聪明的 ImmutableList.copyOf(foobar) 会直接返回 foobar.asList(),是这个 ImmutableSet 的常量时间复杂度的拷贝。
作为一般性的探索,ImmutableXXX.copyOf(ImmutableCollection) 会尽量避免线性时间复杂度的拷贝,如果
- 基础数据结构可以在常量时间复杂度内使用。例如, ImmutableSet.copyOf(ImmutableList) 无法在常量时间内完成。
- 不会引起内存泄漏——例如,如果有一个很大的 ImmutableList<String> hugeList ,然后执行 ImmutableList.copyOf(hugeList.subList(0, 10)),会进行显式的拷贝,为了避免无意中保持着对 hugeList 中不必要的元素的引用。
- 不会改变语义 —— 所以,ImmutableSet.copyOf(myImmutableSortedSet) 会进行显式的拷贝,因为 ImmutableSet 使用的 hashCode() 和 equals 与依赖 comparator 的 ImmutableSortedSet 语义不同。
这帮助了良好的防御式编程减小性能开销。
asList
所有的不可变集合都提供了转化为 ImmutableList 的方法 asList()。因此——例如——即使你把数据存为 ImmutableSortedSet 格式,你也可以用 sortedSet.asList().get(k) 得到第k个最小元素。
返回的 ImmutableList 经常是——并不是每次,但是经常——一个常量时间得到的副本,而不是显式的靠别。也就是说,它一般比普通的 List 要聪明——例如,它会知道调用底层结构的更有效率的 contains 方法。
细节
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 |
中文翻译自Guava官方文档:GuavaExplained - ImmutableCollectionsExplained 译者:戴仓薯
[Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)的更多相关文章
- [Guava官方文档翻译] 1.Guava简介 (Introduction)
用户指南 Guava包含Google在Java项目中用到的一些核心库:collections, caching, primitives support, concurrency 库, common a ...
- [Guava官方文档翻译] 5. Guava的Object公共方法 (Common Object Utilities Explained)
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537367.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- Java基础 @org.junit.Test-单元测试方法 + 操纵Collection和Map的工具类 : Collections 的sort/binarySearch/max/min等静态方法
单元测试代码: ( 在IDEA中先输入'@Test '然后根据提示进行自动修订即可!!运行时直接运行即可! 若有多个单元测试块的时候,直接把鼠标放在哪里就自动在哪里运行那个单元块) import ...
- [Guava官方文档翻译] 2.使用和避免使用null (Using And Avoiding Null Explained)
本文地址:http://www.cnblogs.com/hamhog/p/3536647.html "null很恶心." -Doug Lea "这是一个令我追悔莫及的错误 ...
- .Net中的不可变集合(Immutable Collection)简介
今天发现MS在Nuget上发布了一个Immutable Collection的程序集,提供了对不可变对象的集合的支持. 简单的看了一下,貌似支持的还比较全: ImmutableArray<T&g ...
- [Guava官方文档翻译] 4. 使用Guava Ordering排序 (Ordering Explained)
本文地址:http://www.cnblogs.com/hamhog/p/3537233.html 示例 assertTrue(byLengthOrdering.reverse().isOrdered ...
- [Guava官方文档翻译] 6. 用Guava辅助Throwable异常处理 (Throwables Explained)
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537508.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...
- [Guava官方文档翻译] 3. 前置条件检查(Preconditions Explained)
本文地址:http://www.cnblogs.com/hamhog/p/3536964.html 前置条件检查 Guava提供了一些检查前置条件的utilities.我们强烈建议静态import这些 ...
- Immutable(不可变)集合
不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 对不可靠的客户代 ...
随机推荐
- Oracle DECODE函数的语法介绍
Oracle DECODE函数功能很强,下面就为您详细介绍Oracle DECODE函数的用法,希望可以让您对Oracle DECODE函数有更多的了解. Oracle DECODE函数 Oracle ...
- 解决ecshop在线客户点击无法唤醒QQ问题
找到default/library/page_footer.lbi中找到QQ代码的相应位置,然后你会发现之前模板里面为什么QQ点击不能对话,是因为QQ客服安装包中的JS代码有的可能是比较旧的代码了. ...
- Ps切图学习
1.切图的原文件格式为psd,用ps工具打开 2.鼠标点击需要切的图片,会自动选中图层: 3.选择需要切图的图层,右键复制图层 宽高必须为2的倍数 文件-存储为web和设备所用格式 预设选择为png- ...
- eclipse+webservice开发实例
1.參考文献: 1.利用Java编写简单的WebService实例 http://nopainnogain.iteye.com/blog/791525 2.Axis2与Eclipse整合开发Web ...
- JS字符处理
JS取整 1.toFixed(num)(ps:num为保留小数点后几位) 自定义保留小数点后几位,进行四舍五入.严格来说,这个函数不属于取整,但是当num=0时,也就是取整了,所以一起放到这里,方便查 ...
- Android在线更新 远程安装程序
原文:http://blog.csdn.net/jasper_success/article/details/7984065 第一步:使用java.net的URLConnection对象来创建连接 第 ...
- dialog统一标准调用方法(内部记录)
更新base-config.js 对话框统一为三种形式(如后期需要再添加其他方式) //对话框--确定取消 //dialogOkFun:确定函数 dialogCancelFun:取消函数 functi ...
- eclipse中web项目部署以后jsp的java文件找不到问题(Tomcat配置serverlocations)
我的开发环境:eclipse kepler (4.3)+tomcat7.0.42. 在我想看eclipse中web项目jsp文件被tomcat转换成java以后的java源文件的位置,发现正常情况下的 ...
- 重现PHP Core的调用栈
以前, 我曾经介绍过如何通过PHP的Core文件获取信息:如何调试PHP的Core之获取基本信息, 对于调用参数这块, 当时介绍的获取方法比较复杂. 于是今天我为PHP 5.4的.gdbini ...
- 文件夹添加右键DOS快捷入口
1.自带的方法 win7: 按住shift键然后右键点击文件夹,菜单里会出现“在此处打开命令窗口”一项,其实就相当于在当前位置打开Dos窗口,这个是系统自带的. winxp: 打开“我的电脑”,点击菜 ...