[Google Guava] 2.1-不可变集合

范例

01    public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
02            "red",
03            "orange",
04            "yellow",
05            "green",
06            "blue",
07            "purple");
08
09    class Foo {
10        Set<Bar> bars;
11        Foo(Set<Bar> bars) {
12            this.bars = ImmutableSet.copyOf(bars); // defensive copy!
13        }
14    }

为什么要使用不可变集合

不可变对象有很多优点,包括:

  • 当对象被不可信的库调用时,不可变形式是安全的;
  • 不可变对象被多个线程调用时,不存在竞态条件问题
  • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
  • 不可变对象因为有固定不变,可以作为常量来安全使用。

创建对象的不可变拷贝是一项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本。
 JDK也提供了Collections.unmodifiableXXX方法把集合包装为不可变形式,但我们认为不够好:

  • 笨重而且累赘:不能舒适地用在所有想做防御性拷贝的场景;
  • 不安全:要保证没人通过原集合的引用进行修改,返回的集合才是事实上不可变的;
  • 低效:包装过的集合仍然保有可变集合的开销,比如并发修改的检查、散列表的额外空间,等等。

如果你没有修改某个集合的需求,或者希望某个集合保持不变时,把它防御性地拷贝到不可变集合是个很好的实践。

重要提示:所有Guava不可变集合的实现都不接受null值。我们对Google内部的代码库做过详细研究,发现只有5%的情况需要在集合中允许null元素,剩下的95%场景都是遇到null值就快速失败。如果你需要在不可变集合中使用null,请使用JDK中的Collections.unmodifiableXXX方法。更多细节建议请参考“使用和避免null”

怎么使用不可变集合

不可变集合可以用如下多种方式创建:

  • copyOf方法,如ImmutableSet.copyOf(set);
  • of方法,如ImmutableSet.of(“a”, “b”, “c”)或 ImmutableMap.of(“a”, 1, “b”, 2);
  • Builder工具,如
1    public static final ImmutableSet<Color> GOOGLE_COLORS =
2            ImmutableSet.<Color>builder()
3                .addAll(WEBSAFE_COLORS)
4                .add(new Color(0, 191, 255))
5                .build();

此外,对有序不可变集合来说,排序是在构造集合的时候完成的,如:

1    ImmutableSortedSet.of("a", "b", "c", "a", "d", "b");

会在构造时就把元素排序为a, b, c, d。

比想象中更智能的copyOf

请注意,ImmutableXXX.copyOf方法会尝试在安全的时候避免做拷贝——实际的实现细节不详,但通常来说是很智能的,比如:

1    ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz");
2    thingamajig(foobar);
3
4    void thingamajig(Collection<String> collection) {
5        ImmutableList<String> defensiveCopy = ImmutableList.copyOf(collection);
6        ...
7    }

在这段代码中,ImmutableList.copyOf(foobar)会智能地直接返回foobar.asList(),它是一个ImmutableSet的常量时间复杂度的List视图。
作为一种探索,ImmutableXXX.copyOf(ImmutableCollection)会试图对如下情况避免线性时间拷贝:

  • 在常量时间内使用底层数据结构是可能的——例如,ImmutableSet.copyOf(ImmutableList)就不能在常量时间内完成。
  • 不会造成内存泄露——例如,你有个很大的不可变集合ImmutableList<String>
    hugeList, ImmutableList.copyOf(hugeList.subList(0, 10))就会显式地拷贝,以免不必要地持有hugeList的引用。
  • 不改变语义——所以ImmutableSet.copyOf(myImmutableSortedSet)会显式地拷贝,因为和基于比较器的ImmutableSortedSet相比,ImmutableSet对hashCode()和equals有不同语义。

在可能的情况下避免线性拷贝,可以最大限度地减少防御性编程风格所带来的性能开销。

asList视图

所有不可变集合都有一个asList()方法提供ImmutableList视图,来帮助你用列表形式方便地读取集合元素。例如,你可以使用sortedSet.asList().get(k)从ImmutableSortedSet中读取第k个最小元素。

asList()返回的ImmutableList通常是——并不总是——开销稳定的视图实现,而不是简单地把元素拷贝进List。也就是说,asList返回的列表视图通常比一般的列表平均性能更好,比如,在底层集合支持的情况下,它总是使用高效的contains方法。

细节:关联可变集合和不可变集合

可变集合接口 属于JDK还是Guava 不可变版本
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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: [Google Guava] 2.1-不可变集合

原文地址:https://www.cnblogs.com/muxi0407/p/12016319.html

时间: 2024-11-06 18:54:36

[Google Guava] 2.1-不可变集合的相关文章

【java代码之美】---guava之Immutable(不可变)集合

Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类. Guava中不可变对象和Collections工具类的unmodifiableSet/List/Map/etc的区别: 当Collections创建的不可变集合的wrapper类改变的时候,不可变集合也会改变,而Guava的Immutable集合保证确实是不可变的. 1.JDK中实现immuta

Guava学习笔记:guava的不可变集合

Guava学习笔记:guava的不可变集合 不可变集合的意义 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态条件问题 不可变集合不需要考虑变化,因此可以节省时间和空间.所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节): 不可变对象因为有固定不变,可以作为常量来安全使用. 创建对象的不可变拷贝是一项很好的防御性编程技巧.Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本. 

Guava学习笔记:Immutable(不可变)集合

不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象 2.线程安全的:immutable对象在多线程下安全,没有竞态条件 3.不需要支持可变性, 可以尽量节省空间和时间的开销. 所有的不可变集合实现都比可变集合更加有效的利用内存 (analysis) 4.可以被使用为一个常量,并且期望

[Guava学习笔记]Collections: 不可变集合, 新集合类型

不可变集合 不接受null值. 创建:ImmutableSet.copyOf(set); ImmutableMap.of(“a”, 1, “b”, 2); public static final ImmutableSet<Color> GOOGLE_COLORS = ImmutableSet.<Color>builder() .addAll(WEBSAFE_COLORS) .add(new Color(0, 191, 255)) .build(); 可以有序(如ImmutableS

Google Guava教程

Google Guava官方教程(中文版) 原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives support] .并发库 [concurrency libraries] .通用注解 [common annotations] .字符串处理 [string processing] .I/O

Google Guava简介

Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合(collections).缓存(caching).原生类型支持(primitives support).并发库 (concurrency libraries).通用注解(common annotations).字符串处理(string processing).I/O 等等. 所有这些工具每天都在被Google的工程师应用在产品服务中. 项目信息 首页:https://code.google.com/p/guav

Google Guava 库用法整理&lt;转&gt;

参考: http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports-part-1/(2,3,4) http://blog.publicobject.com 更多用法参考http://ajoo.iteye.com/category/119082 附 guava中文api地址http://ifeve.com/google-guava/ 以前这么用: Java代码   M

[转载]Google Guava官方教程(中文版)

  原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives support] .并发库 [concurrency libraries] .通用注解 [common annotations] .字符串处理 [string processing] .I/O 等等. 所有这些工具每天都在被Goog

Google Guava入门教程

以下资料整理自网络 一.Google Guava入门介绍 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives support] .并发库 [concurrency libraries] .通用注解 [common annotations] .字符串处理 [string processing] .I/O 等等. 所有这些工具每天都在被Google的工程师应用在产品