[Guava源码分析]ImmutableCollection:不可变集合

摘要: 我的技术博客经常被流氓网站恶意爬取转载。请移步原文:http://www.cnblogs.com/hamhog/p/3888557.html,享受整齐的排版、有效的链接、正确的代码缩进、更好的阅读体验。

API

抽象方法

iterator()  
isPartialView() 

标记是否有Collection方法访问不到的非基础类型对象。

用来判断copyOf是否要进行显式拷贝,来避免内存泄漏。

可Override方法

contains(Object)  
asList()  

 

final方法

toArray() toArray(T[])  
add() remove() addAll() removeAll() retainAll() clear() 确保一定会抛出异常

用法

构造方法

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

源码分析

1. asList()

典型的延迟加载:ImmutableCollection类持有一个asList实例。第一次用到时构造,其余直接返回。

返回类型为ImmutableList,实际上是子类RegularImmutableAsList。这个子类包装了一个ImmutableList,在此之外保存了源ImmutableCollection,是一个典型的装饰模式。

构造方法是先把ImmutableCollection转成array,array再转成ImmutableList。

2. 抽象静态类Builder

用来把集合变为不可变集合的抽象工厂。

提供了2类方法的模板:expandedCapacity()、add(E...)/addAll(Iterator)/addAll(Iterable)。这些add多元素方法全部调用add(E)。

两个抽象方法:add(E)和build()

3. 避免copyOf()的内存泄漏

ImmutableCollection在执行copyOf()的时候,为了节省时间,不一定会逐个逐个元素遍历拷贝。但是,如果是个很大的List取出的subList(1,10),不遍历(所谓不显式拷贝)会拷贝一群访问不到的元素,造成内存泄漏。

因此使用isPartialView()方法来避免这种情形;如果含有冗余元素,则进行显式拷贝。

posted @ 2014-08-03 17:26  戴仓薯  阅读(1243)  评论(0编辑  收藏  举报