美文网首页程序员
guava学习笔记系列 - Immutable Collecti

guava学习笔记系列 - Immutable Collecti

作者: robin2016x | 来源:发表于2017-12-08 13:57 被阅读0次

Immutable Collections

个人博客

http://www.taociabc.com/wordpress/2018/01/06/guava%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E7%B3%BB%E5%88%97-immutable-collections/

英文原文 https://github.com/google/guava/wiki/ImmutableCollectionsExplained

不可修改的集合

public static final ImmutableSet COLOR_NAMES = ImmutableSet.of( "red", "orange", "yellow", "green", "blue", "purple");

class Foo {

final ImmutableSet bars;

Foo(Set bars) {

this.bars = ImmutableSet.copyOf(bars); // defensive copy!

}

}

Why?

不可修改的对象有许多优势,包括:

* 可以安全的被不受信任的外部库使用,而不用担心数据被篡改

* 线程安全:可被多线程使用,没有竞争风险

* 不必支持修改,在这种假设前提下可以节省时间和空间,所有不可变的集合实现要比可变的集合更加高效  分析

使对象拷贝不可变是一种好的防御性编程技术,Guava提供了简单、易于使用的多种基本的Collection类型,包括Guava自己的Collection变体。

JDK提供Collections.unmodifiableXXX方法,但从我们的观点看,这些是

* 笨拙和冗长的;在任何你想进行防御性拷贝编程时都不太好用;

* 不安全:在任何人都不持有原始集合的引用时,返回的集合才真的是不可改变的。换言之,JDK提供的实现返回的不可变集合还是可能被改变的

* 低效:数据结构仍然有可变集合的性能开销,包括并发修改检测,占用额外的hash tables空间。

当你不期望修改一个集合,或期望一个集合保持常量状态,一个好的实践就是把它进行防御性拷贝进一个不可变集合中。

How?

一个 ImmutableXXX 集合可以通过许多方式创建:

* 使用 copyOf 方法,例如,ImmutableSet.copyOf(set)

* 使用 of 方法, 例如, ImmutableSet.of("a", "b", "c") 或 ImmutableMap.of("a", 1, "b", 2)

* 使用Builder , 例如:

public static final ImmutableSet GOOGLE_COLORS = ImmutableSet.builder()

.addAll(WEBSAFE_COLORS)

.add(new Color(0, 191, 255))

.build();

除了 sorted collections,顺序会在构造期间保留下来,比如

ImmutableSet.of("a","b","c","a","d","b")

迭代它的元素将得到这样的顺序 "a", "b", "c", "d".

copyOf比你想的更智能

记住ImmutableXXX.copyOf在安全的情况下是尝试避免拷贝数据的,这很有用 -- 额外的细节并没有指定,但是在实现上通常是很智能的,例如:

ImmutableSetfoobar = ImmutableSet.of("foo", "bar", "baz");thingamajig(foobar);void thingamajig(Collectioncollection) { ImmutableListdefensiveCopy = ImmutableList.copyOf(collection);

...

}

在这个代码中,ImmutableList.copyOf(foobar)很聪明的仅仅返回foobar.asList(),从ImmutableSet来看这是一个恒定时间。

一般的情况下,ImmutableXXX.copyOf(ImmutableCollection) 尝试避免线性时间的拷贝,如果

* 它可以使用潜在的数据结构,在恒定的时间下。例如,ImmutableSet.copyOf(ImmutableList)不能在恒定的时间下完成。

* 它不会引起内存泄漏 -- 例如,如果你有一个很大的 ImmutableList hugeList,并且你做ImmutableList.copyOf(hugeList.subList(0, 10))这种操作,则显示的复制,因为这样可以避免意外的引用到hugeList中不必要的元素

* 它不改变语义 -- 因此ImmutableSet.copyOf(myImmutableSortedSet)将执行显示复制,因为ImmutableSet使用的 hashCode() 和 equals与ImmutableSortedSet的基于比较器的行为有不同的语义。

相关文章

网友评论

    本文标题:guava学习笔记系列 - Immutable Collecti

    本文链接:https://www.haomeiwen.com/subject/hvnsixtx.html