Google Guava 集合(Collections)

       这一篇文章我们来讲Google Guava集合,这是Guava最成熟和为人所知的部分。里面给我们提供各个集合的工具类,也给我们提供了一些新的集合类。

一 不可变集合

       不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变,一旦不可变集合创建之后,你是不可以对集合里面的做增,改操作的.我们为什么需要不可变集合,不可变集合的优势在哪里呢:

  • 对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象.
  • 线程安全的:immutable对象在多线程下安全,没有竞态条件
  • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节)
  • 不可变对象因为固定不变,可以作为常量来安全使用

       我们先看下Guava库里面给我们提供了哪些不可变集合,以及这些集合和JDK里面集合的关系.我们直接用表格形式列出,如下所示;

可变集合接口 属于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

1.1 不可变集合的使用

       Guava库里面不可变集合的使用主要在两个方面吧,一个是怎么创建不可变集合,另一个是怎么获取不可变集合里面的元素.关于怎么获取里面的元素,这个咱们不讲.和JDK里面使用集合是一样的.我们接下来要讲的主要在怎么去创建不可变集合.Guava库里面提供的每个不可变集合类都有如下三种方法.

如果你尝试去修改不可变集合会跑出UnsupportedOperationException异常.

  • 调用静态方法of创建.

       of()方法通过给定集合里面的元素来生成不可变集合.

        ImmutableList imutableUserList = ImmutableList.of("jiangxi", "nanchang");
  • 调用静态方法copyOf创建.

       我们可以简单的理解为copyOf方法就是讲对应的JDK集合转换为Guava不可变集合.如果你想将List转换为不可变集合,就使用ImmutableList.copyOf(list)方法,如果想Set装换为不可变集合就调用ImmutableSet.copyOf(set),其他的不可变集合也是类似的.

        List userList = new ArrayList<>();
        userList.add("jiangxi");
        userList.add("nanchang");
        ImmutableList imutableUserList = ImmutableList.copyOf(userList);
  • 调用静态方法build创建.
        ImmutableList imutableUserList = ImmutableList.builder()
                .add("jiangxi")
                .add("nanchang")
                .build();

       Guava库里面每个不可变集合一般都有这三种方法来创建对应的不可变集合.当然了里面还有一些其他的方法,我们都可以到源码里面去看.都是很好理解的一些方法.

二 新集合类型

       Guava引入了很多JDK没有的(multisets, multimaps, tables, bidirectional maps等)、但我们发现明显有用的新集合类型。这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念。作为一般规则,Guava集合非常精准地遵循了JDK接口契约。将白了就是和JDK里面集合的使用是差不多的.

2.1 Multiset

       Guava提供了一个新的Set类型Multiset,它可以多次添加相等的元素到Set里面去.Multiset有很多实现类.这个我们放下面讲.我们先看下Multiset里面的主要方法:

方法 描述
count(E) 给定元素在Multiset中的计数
elementSet() Multiset中不重复元素的集合,类型为Set
entrySet() 和Map的entrySet类似,返回Set>,其中包含的Entry支持getElement()和getCount()方法
add(E, int) 增加给定元素在Multiset中的计数
remove(E, int) 减少给定元素在Multiset中的计数
setCount(E, int) 设置给定元素在Multiset中的计数,不可以为负数
size() 返回集合元素的总个数(包括重复的元素)

       Guava提供了多种Multiset的实现类,大部分都是和JDK中Set类一一对应的,有些也是Guava特有的.

Multiset实现类 JDK对应 内部实现
HashMultiset HashSet HashMap
TreeMultiset TreeSet TreeMap
LinkedHashMultiset LinkedHashSet LinkedHashMap
ConcurrentHashMultiset LinkedHashSet ConcurrentHashMap
ImmutableMultiset ImmutableMap
SortedMultiset SortedMultiset是Multiset 接口的变种,支持排序

2.3 Multimap

       每个有经验的Java程序员都在某处实现过Map>或Map>,并且要忍受这个结构的笨拙。例如,Map>通常用来表示非标定有向图。Guava的 Multimap可以很容易地把一个键映射到多个值。换句话说,Multimap是把键映射到任意多个值的一般方式。说白了就是一个key可以对应多个value.Multimap的使用和咱JDK里面Map的使用是类似的.

       Multimap的各种实现类.

Multimap实现类 键行为类似 行为类似
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap* LinkedHashMap LinkedList*
LinkedHashMultimap** LinkedHashMap LinkedHashMap
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
mmutableSetMultimap ImmutableMap ImmutableSet

2.4 BiMap

       BiMap是特殊的Map.BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构。平常咱们用的最多的都是通过key获取value.但是反过来通过value获取key就比较复杂了.BiMap就是来解决这个问题的.BiMap有一个神奇的方法BiMap inverse().可以把Map里面的key,value反过来.BiMap里面key和value都是唯一的不能重复.

对应的BiMap实现 键–值实现 值–键实现
HashBiMap HashMap HashMap
ImmutableBiMap ImmutableMap ImmutableMap
EnumBiMap EnumMap EnumMap
EnumHashBiMap EnumMap HashMap

关于BiMap里面各个类api方法,我们就不展示出来.都是很容易懂的.源码点击去,啥都晓得了.源码才是最讲道理的地方.

2.5 Table

       当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map>来实现。为此Guava提供了一个新的集合类型-Table集合类型,来支持这种数据结构的使用场景。Table支持“row”和“column”,Table是Guava提供的一个接口 Interface Table,由rowKey+columnKey+value组成它有两个键,一个值,和一个n行三列的数据表类似,n行取决于Table对对象中存储了多少个数据.

对于Table而言里面的每个value都有两个key(rowKey,columnKey)

       Table主要方法介绍,每个方法其实都很好理解:


public interface Table {


    /**
     * 指定行,列对应的值是否存在
     */
    boolean contains(
            @Nullable @CompatibleWith("R") Object rowKey,
            @Nullable @CompatibleWith("C") Object columnKey);

    /**
     * 指定行对应的值是否存在
     */
    boolean containsRow(@Nullable @CompatibleWith("R") Object rowKey);

    /**
     * 指定列对应的值是否存在
     */
    boolean containsColumn(@Nullable @CompatibleWith("C") Object columnKey);

    /**
     * 值是否存在
     */
    boolean containsValue(@Nullable @CompatibleWith("V") Object value);

    /**
     * 获取指定行,列对应的值
     */
    V get(
            @Nullable @CompatibleWith("R") Object rowKey,
            @Nullable @CompatibleWith("C") Object columnKey);

    /** Returns {@code true} if the table contains no mappings. */
    boolean isEmpty();

    /** 获取元素个数 */
    int size();
    

    // Mutators

    /** 清空 */
    void clear();

    /**
     * 放入元素
     */
    @CanIgnoreReturnValue
    @Nullable
    V put(R rowKey, C columnKey, V value);

    /**
     * 放入元素
     */
    void putAll(Table table);

    /**
     * 移除元素
     */
    @CanIgnoreReturnValue
    @Nullable
    V remove(
            @Nullable @CompatibleWith("R") Object rowKey,
            @Nullable @CompatibleWith("C") Object columnKey);
    

    /**
     * 指定行的所有数据
     */
    Map row(R rowKey);

    /**
     * 指定列的所有数据
     */
    Map column(C columnKey);

    /**
     * 用元素类型为Table.Cell的Set表现Table。
     * Cell类似于Map.Entry,但它是用行和列两个键区分的。
     */
    Set> cellSet();

    /**
     * 获取Table里面所有行的key
     */
    Set rowKeySet();

    /**
     * 获取Table里面所有列的key
     */
    Set columnKeySet();

    /**
     * 获取Table里面所有的值
     */
    Collection values();

    /**
     * 用Map>表现Table
     */
    Map> rowMap();

    /**
     * 用Map>表现Table
     */
    Map> columnMap();
}

       Table的实现类,以及内部是用啥数据类型实现的.

对应的Table实现 内部实现
HashBasedTable HashMap>
TreeBasedTable TreeMap>
ImmutableTable ImmutableMap>
ArrayTable 二维数组

2.6 ClassToInstanceMap

       ClassToInstanceMap提供了一种是用Class作为Key, 对应实例作为Value的途径.他定义了T getInstance(Class)和T putInstance(Class T)两个方法, 这两个方法消除了元素类型转换的过程并保证了元素在Map中是类型安全的.我们使用ClassToInstanceMap的唯一目的就是消除类型转换过程中可能产生的错误.比如在传递参数的时候我们就可以用上ClassToInstanceMap了.

ClassToInstanceMap实现类 解释
MutableClassToInstanceMap 可变类型的ClassToInstanceMap
ImmutableClassToInstanceMap 不可变更的ClassToInstanceMap,我们在对这个Map构造完成后就不可再变更

        ClassToInstanceMap classToInstanceMap = MutableClassToInstanceMap.create();
        classToInstanceMap.putInstance(Integer.class, 10);
        classToInstanceMap.putInstance(Float.class, 10L);
        classToInstanceMap.putInstance(String.class, "abc");

2.7 RangeSet

       RangeSet描述了一组不相连的、非空的区间。当把一个区间添加到可变的RangeSet时,所有相连的区间会被合并,空区间会被忽略。

       关于RangeSet咱们的关注点在两个方面:一个是RangeSet的值是可以比较的所以RangeSet里面的值对应的对象需要实现Comparable接口、第二个是范围,guava里面通过Range类来表示范围。关于Range里面方法我们也做一个简单的介绍(不同的函数代表不同的区间),如下:

概念 表示范围 guava Range类对应方法
(a..b) {x a < x < b} open(C, C)
[a..b] {x a <= x <= b} closed(C, C)
[a..b) {x a <= x < b} closedOpen(C, C)
(a..b] {x a < x <= b} openClosed(C, C)
(a..+∞) {x x > a} greaterThan(C)
[a..+∞) {x x >= a} atLeast(C)
(-∞..b) {x x < b} lessThan(C)
(-∞..b] {x x <= b} atMost(C)
(-∞..+∞) all values all()

       RangeSet方法介绍,如下:

public interface RangeSet {

    /** 是否包含值 */
    boolean contains(C value);

    /**
     * 获取值所在的区间
     */
    Range rangeContaining(C value);

    /**
     * 判断RangeSet中是否有任何区间和给定区间交叉
     */
    boolean intersects(Range otherRange);

    /**
     * 判断RangeSet中是否有任何区间包括给定区间
     */
    boolean encloses(Range otherRange);

    /**
     * 同上,如果RangeSet的范围都在当前RangeSet里面则返回true
     */
    boolean enclosesAll(RangeSet other);

    /**
     * 同上,给定的参数的范围都在当前RangeSet里面则返回true
     */
    default boolean enclosesAll(Iterable> other) {
        for (Range range : other) {
            if (!encloses(range)) {
                return false;
            }
        }
        return true;
    }

    /** 是否为null */
    boolean isEmpty();

    /**
     * 返回包括RangeSet中所有区间的最小区间
     */
    Range span();


    /**
     * 用Set>表现RangeSet,这样可以遍历其中的Range
     */
    Set> asRanges();

    /**
     * 返回组成此范围集的断开连接的范围的降序视图
     */
    Set> asDescendingSetOfRanges();

    /**
     * 返回RangeSet的补集视图。complement也是RangeSet类型,包含了不相连的、非空的区间。
     */
    RangeSet complement();

    /**
     * 返回RangeSet与给定Range的交集视图。这扩展了传统排序集合中的headSet、subSet和tailSet操作
     */
    RangeSet subRangeSet(Range view);


    /**
     * 增加一个范围区间
     */
    void add(Range range);

    /**
     * 移除一个范围区间,如果有交叉的话,会被分割
     */
    void remove(Range range);

    /**
     * 清空
     */
    void clear();

    /**
     * 增加参数里面所有的区间到当前RangeSet里面去
     */
    void addAll(RangeSet other);

    /**
     * 同上把参数给定的区间都增加到当前RangeSet里面去
     */
    default void addAll(Iterable> ranges) {
        for (Range range : ranges) {
            add(range);
        }
    }

    /**
     * 移除参数给定的所有区间,如果有交集的情况会拆分
     */
    void removeAll(RangeSet other);

    /**
     * 移除参数给定的所有区间,如果有交集的情况会拆分
     */
    default void removeAll(Iterable> ranges) {
        for (Range range : ranges) {
            remove(range);
        }
    }


}

       RangeSet实现类,guava提供了两个实现类,有兴趣的也可以进去看看源码,如下:

RangeSet实现类 解释
ImmutableRangeSet 是一个不可修改的RangeSet
TreeRangeSet 利用树的形式来实现

       RangeSet简单使用

        RangeSet rangeSet = TreeRangeSet.create();
        rangeSet.add(Range.closed(1, 10));
        System.out.println(rangeSet);   // [[1..10]]

        rangeSet.add(Range.closedOpen(11, 15));
        System.out.println(rangeSet);   // [[1..10], [11..15)]

        rangeSet.add(Range.open(15, 20));
        System.out.println(rangeSet);   // [[1..10], [11..15), (15..20)]

        rangeSet.add(Range.openClosed(0, 0));
        System.out.println(rangeSet);   // [[1..10], [11..15), (15..20)]

        rangeSet.remove(Range.open(5, 10));
        System.out.println(rangeSet);   // [[1..5], [10..10], [11..15), (15..20)]

2.8 RangeMap

       angeMap描述了”不相交的、非空的区间”到特定值的映射。和RangeSet不同,RangeMap不会合并相邻的映射,即便相邻的区间映射到相同的值。说的简单直白一点RangeMap就是以区间作为键。

       RangeMap方法介绍,如下:

public interface RangeMap {
    /**
     * 获取范围对应的元素(子范围也是可以的)
     */
    @Nullable
    V get(K key);

    /**
     * 如果范围映射中存在此类范围,则返回包含此键及其关联值的范围
     * 1. 先根据范围找到值
     * 2. 在根据值找到,所有范围
     */
    @Nullable
    Map.Entry, V> getEntry(K key);

    /**
     * 返回包含此RangeMap中范围的最小范围
     */
    Range span();

    /**
     * 放入一个元素
     */
    void put(Range range, V value);

    /**
     * 将范围映射到指定值,将此范围与具有与此范围相连的相同值的任何现有范围合并
     */
    void putCoalescing(Range range, V value);

    /** 放入值 */
    void putAll(RangeMap rangeMap);

    /** 清空 */
    void clear();

    /**
     * 移除
     */
    void remove(Range range);

    /**
     * 将此范围映射的视图作为不可修改的Map返回
     */
    Map, V> asMapOfRanges();

    /**
     * 将此范围映射的视图作为不可修改的Map返回
     */
    Map, V> asDescendingMapOfRanges();

    /**
     * 返回此范围映射的与范围相交的部分的视图
     */
    RangeMap subRangeMap(Range range);
}

       RangeMap有两个实现类。有兴趣的大家可以看看源码。

RangeMap实现类 解释
ImmutableRangeMap 不可以修改的RangeMap
TreeRangeMap 利用树的形式来实现

       RangeMap简单使用:

        RangeMap rangeMap = TreeRangeMap.create();
        rangeMap.put(Range.closed(1, 10), "foo"); //{[1,10] => "foo"}
        rangeMap.put(Range.open(3, 6), "bar"); //{[1,3] => "foo", (3,6) => "bar", [6,10] => "foo"}
        rangeMap.put(Range.open(10, 20), "foo"); //{[1,3] => "foo", (3,6) => "bar", [6,10] => "foo", (10,20) => "foo"}
        rangeMap.remove(Range.closed(5, 11)); //{[1,3] => "foo", (3,5) => "bar", (11,20) => "foo"}

三 强大的集合工具类

       提供java.util.Collections中没有的集合工具。任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法。Guava沿着这些路线提供了更多的工具方法:适用于所有集合的静态方法。这是Guava最流行和成熟的部分之一。

集合接口 属于JDK还是Guava 对应的Guava工具类
Iterable JDK Iterables
Collection JDK Collections2:不要和java.util.Collections混淆
List JDK Lists
Set JDK Sets
SortedSet JDK Sets
Map JDK Maps
SortedMap JDK Maps
Queue JDK Queues
Multiset Guava Multisets
Multimap Guava Multimaps
BiMap Guava Maps
Table Guava Tables

3.1 Iterables

public final class Iterators {

    /**
     * 返回不可修改的迭代器
     */
    public static  Iterable unmodifiableIterable(final Iterable iterable);
    @Deprecated
    public static  Iterable unmodifiableIterable(ImmutableCollection iterable);


    /** 元素个数 */
    public static int size(Iterable iterable);

    /**
     * 是否包含指定元素
     */
    public static boolean contains(Iterable iterable, @Nullable Object element);

    /**
     * 移除集合类的元素
     */
    @CanIgnoreReturnValue
    public static boolean removeAll(Iterable removeFrom, Collection elementsToRemove);

    /**
     * 交集,完全属于
     */
    @CanIgnoreReturnValue
    public static boolean retainAll(Iterable removeFrom, Collection elementsToRetain);

    /**
     * 移除满足条件的元素
     */
    @CanIgnoreReturnValue
    public static  boolean removeIf(Iterable removeFrom, Predicate predicate);

    /** 移除第一个满足添加的元素,并且返回该元素 */
    static  @Nullable T removeFirstMatching(
            Iterable removeFrom, Predicate predicate);

    /**
     * 如果两个iterable中的所有元素相等且顺序一致,返回true
     */
    public static boolean elementsEqual(Iterable iterable1, Iterable iterable2);

    /**
     * 获取iterable中唯一的元素,如果iterable为空或有多个元素,则快速失败
     */
    public static  T getOnlyElement(Iterable iterable);
    public static  @Nullable T getOnlyElement(
            Iterable iterable, @Nullable T defaultValue);

    /**
     * 返回迭代器里面满足指定类型的元素对应的数据
     */
    @GwtIncompatible // Array.newInstance(Class, int)
    public static  T[] toArray(Iterable iterable, Class type);

    /**
     * 把迭代器里面的元素放入到数组里面去
     */
    static  T[] toArray(Iterable iterable, T[] array);

    /**
     * 把迭代器里面的元素放入到数组里面去
     */
    static Object[] toArray(Iterable iterable);

    /**
     * 把迭代器里面的元素放入到集合里面去
     */
    private static  Collection castOrCopyToCollection(Iterable iterable);

    /**
     * 集合里面的元素都添加到迭代器里面去
     */
    @CanIgnoreReturnValue
    public static  boolean addAll(Collection addTo, Iterable elementsToAdd);

    /**
     * 返回对象在iterable中出现的次数
     */
    public static int frequency(Iterable iterable, @Nullable Object element) {
        if ((iterable instanceof Multiset)) {
            return ((Multiset) iterable).count(element);
        } else if ((iterable instanceof Set)) {
            return ((Set) iterable).contains(element) ? 1 : 0;
        }
        return Iterators.frequency(iterable.iterator(), element);
    }

    /**
     * 返回一个循环迭代器,可以比作是双向链表,最后一个又和第一个连接起来
     */
    public static  Iterable cycle(final Iterable iterable);
    @SafeVarargs
    public static  Iterable cycle(T... elements);

    /**
     * 串联起来
     */
    public static  Iterable concat(Iterable a, Iterable b);
    public static  Iterable concat(
            Iterable a, Iterable b, Iterable c)
    public static  Iterable concat(
            Iterable a,
            Iterable b,
            Iterable c,
            Iterable d);
    @SafeVarargs
    public static  Iterable concat(Iterable... inputs);
    public static  Iterable concat(Iterable> inputs);

    /**
     * 对迭代器做划分,多少个元素一组, 每个分组没满个数的会填null
     * [a, b, c, d, e]} with a partition size of 3 yields {[[a, b, c], [d, e, null]]}
     */
    public static  Iterable> partition(final Iterable iterable, final int size);

    /**
     * 对迭代器做划分,多少个元素一组, 每个分组没满个数的会填null
     * [a, b, c, d, e]} with a partition size of 3 yields {[[a, b, c], [d, e]]}
     */
    public static  Iterable> paddedPartition(final Iterable iterable, final int size);

    /**
     * 过滤出满足条件的值
     */
    public static  Iterable filter(
            final Iterable unfiltered, final Predicate retainIfTrue);

    /**
     * 过滤出指定类型的元素
     */
    @SuppressWarnings("unchecked")
    @GwtIncompatible // Class.isInstance
    public static  Iterable filter(final Iterable unfiltered, final Class desiredType);

    /**
     * 迭代器里面只要有一个元素满足条件就返回true
     */
    public static  boolean any(Iterable iterable, Predicate predicate);

    /**
     * 迭代器里面的每个元素是否都满足条件
     */
    public static  boolean all(Iterable iterable, Predicate predicate);

    /**
     * 获取满足条件的值
     */
    public static  T find(Iterable iterable, Predicate predicate);

    /**
     * 获取满足条件的值,如果没有找到返回defaultValue
     */
    public static  @Nullable T find(
            Iterable iterable, Predicate predicate, @Nullable T defaultValue);

    /**
     * 获取满足条件的值,值用Optional报装
     */
    public static  Optional tryFind(Iterable iterable, Predicate predicate);

    /**
     * 获取满足条件记录的位置
     */
    public static  int indexOf(Iterable iterable, Predicate predicate);

    /**
     * 对迭代器里面的每个记录做相应的转换
     */
    public static  Iterable transform(
            final Iterable fromIterable, final Function function);

    /**
     * 获取指定位置记录
     */
    public static  T get(Iterable iterable, int position);

    /**
     * 获取指定位置的的记录,如果没有找到返回defaultValue
     */
    public static  @Nullable T get(
            Iterable iterable, int position, @Nullable T defaultValue);

    /**
     * 获取第一个记录,如果没有找到就用defaultValue代替
     */
    public static  @Nullable T getFirst(Iterable iterable, @Nullable T defaultValue);

    /**
     * 获取最后一个记录
     */
    public static  T getLast(Iterable iterable);

    /**
     * 获取最后一个记录,如果没有获取到就是defaultValue
     */
    public static  @Nullable T getLast(Iterable iterable, @Nullable T defaultValue);

    /**
     * 获取最后一个记录
     */
    private static  T getLastInNonemptyList(List list);

    /**
     * 返回跳过指定元素的Iterable
     */
    public static  Iterable skip(final Iterable iterable, final int numberToSkip);

    /**
     * 返回一个(可能)被截取的iterable,元素个数最多为给定值
     */
    public static  Iterable limit(final Iterable iterable, final int limitSize);

    /**
     * 返回一个用于过滤、转换集合中的数据
     */
    public static  Iterable consumingIterable(final Iterable iterable);

    // Methods only in Iterables, not in Iterators

    /**
     * 判断可迭代对象元素是否为null
     */
    public static boolean isEmpty(Iterable iterable);

    /**
     * 获取排序之后的可迭代对象
     */
    @Beta
    public static  Iterable mergeSorted(
            final Iterable> iterables,
            final Comparator comparator);

}

3.2 Collections2

public final class Collections2 {

    /**
     * 过滤
     */
    public static  Collection filter(Collection unfiltered, Predicate predicate);

    /**
     * 转换
     */
    public static  Collection transform(
            Collection fromCollection, Function function);

    /**
     * 先将元素排序,在排列
     */
    @Beta
    public static > Collection> orderedPermutations(
            Iterable elements);
    @Beta
    public static  Collection> orderedPermutations(
            Iterable elements, Comparator comparator);

    /**
     * 直接排列
     */
    @Beta
    public static  Collection> permutations(Collection elements);

}

3.3 Lists

public final class Lists {

    /**
     * 构造ArrayList
     */
    @GwtCompatible(serializable = true)
    public static  ArrayList newArrayList();
    @SafeVarargs
    @GwtCompatible(serializable = true)
    public static  ArrayList newArrayList(E... elements);
    @GwtCompatible(serializable = true)
    public static  ArrayList newArrayList(Iterable elements);
    @GwtCompatible(serializable = true)
    public static  ArrayList newArrayList(Iterator elements);
    

    /**
     * 构造一个带初始化带大小initialArraySize的ArrayList实例
     */
    @GwtCompatible(serializable = true)
    public static  ArrayList newArrayListWithCapacity(int initialArraySize);

    /**
     * 构造一个期望长度为estimatedSize的ArrayList实例
     */
    @GwtCompatible(serializable = true)
    public static  ArrayList newArrayListWithExpectedSize(int estimatedSize);

    // LinkedList

    /**
     * 获取LinkedList
     */
    @GwtCompatible(serializable = true)
    public static  LinkedList newLinkedList();
    @GwtCompatible(serializable = true)
    public static  LinkedList newLinkedList(Iterable elements);

    /**
     * CopyOnWriteArrayList 读写分离,线程安志的List
     */
    @GwtIncompatible // CopyOnWriteArrayList
    public static  CopyOnWriteArrayList newCopyOnWriteArrayList();
    @GwtIncompatible // CopyOnWriteArrayList
    public static  CopyOnWriteArrayList newCopyOnWriteArrayList(
            Iterable elements);

    /**
     * 转坏为List
     */
    public static  List asList(@Nullable E first, E[] rest);
    public static  List asList(@Nullable E first, @Nullable E second, E[] rest);


    /**
     * 对集合做笛卡尔操作
     * 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}
     */
    public static  List> cartesianProduct(List> lists);
    @SafeVarargs
    public static  List> cartesianProduct(List... lists);

    /**
     * 对list里面的每个元素做转换
     */
    public static  List transform(
            List fromList, Function function);



    /**
     * 对list做分区处理
     */
    public static  List> partition(List list, int size);


    /**
     * String转换成不可变更的ImmutableList
     */
    public static ImmutableList charactersOf(String string);

    /**
     * CharSequence转list
     */
    @Beta
    public static List charactersOf(CharSequence sequence);

    /**
     * 反转
     */
    public static  List reverse(List list);


}

3.4 Sets

public final class Sets {

    /**
     * 返回一个包含给定枚举元素的不可变的Set实例
     */
    // http://code.google.com/p/google-web-toolkit/issues/detail?id=3028
    @GwtCompatible(serializable = true)
    public static > ImmutableSet immutableEnumSet(
            E anElement, E... otherElements);
    @GwtCompatible(serializable = true)
    public static > ImmutableSet immutableEnumSet(Iterable elements);


    /**
     * 返回一个Collector
     */
    public static > Collector> toImmutableEnumSet();

    /**
     * 返回一个EnumSet实例
     */
    public static > EnumSet newEnumSet();

    // HashSet

    /**
     * 返回一个可变的HashSet实例
     */
    public static  HashSet newHashSet();
    public static  HashSet newHashSet(E... elements);
    public static  HashSet newHashSet(Iterable elements);
    public static  HashSet newHashSet(Iterator elements);

    /**
     * 构造一个期望长度为expectedSize的HashSet实例
     */
    public static  HashSet newHashSetWithExpectedSize(int expectedSize);

    /**
     * 创建一个线程安全的Set,由ConcurrentHashMap的实例支持,因此进行了相同的并发性担保,
     * 与HashSet不同的是,这个Set不允许null元素,该Set是可序列化的。
     */
    public static  Set newConcurrentHashSet();

    /**
     * 创建一个线程安全的Set,包含给定的元素,由ConcurrentHashMap的实例支持,因此进行了相同的并发性担保,
     * 与 HashSet不同的是,这个Set不允许null元素,该Set是可序列化的
     */
    public static  Set newConcurrentHashSet(Iterable elements);

    // LinkedHashSet

    /**
     * 创建一个可变的、空的LinkedHashSet实例
     */
    public static  LinkedHashSet newLinkedHashSet();

    /**
     * 构造一个包含给定元素的LinkedHashSet实例
     */
    public static  LinkedHashSet newLinkedHashSet(Iterable elements);

    /**
     * 构造一个期望长度为expectedSize的LinkedHashSet实例
     */
    public static  LinkedHashSet newLinkedHashSetWithExpectedSize(int expectedSize);

    // TreeSet

    /**
     * 返回一个可变的空的TreeSet实例
     */
    public static  TreeSet newTreeSet();

    /**
     * 返回一个可变的包含给定元素的TreeSet实例
     */
    public static  TreeSet newTreeSet(Iterable elements);

    /**
     * 创建一个具有给定的比较器可变TreeSet的实例
     */
    public static  TreeSet newTreeSet(Comparator comparator);

    /**
     * 创建一个空的Set
     */
    public static  Set newIdentityHashSet() {
        return Collections.newSetFromMap(Maps.newIdentityHashMap());
    }

    /**
     * 生成一个CopyOnWriteArraySet,CopyOnWriteArraySet读写分离,线程安全
     */
    @GwtIncompatible // CopyOnWriteArraySet
    public static  CopyOnWriteArraySet newCopyOnWriteArraySet();
    @GwtIncompatible // CopyOnWriteArraySet
    public static  CopyOnWriteArraySet newCopyOnWriteArraySet(Iterable elements);

    /**
     * 创建一个枚举EnumSet
     */
    public static > EnumSet complementOf(Collection collection);

    /**
     * 创建一个枚举EnumSet,并且里面是值是除了type类型之外的值
     */
    public static > EnumSet complementOf(
            Collection collection, Class type);


    /**
     * 基于指定的Map对象创建一个新的Set对象
     */
    @Deprecated
    public static  Set newSetFromMap(Map map);


    /**
     * 合集,并集
     */
    public static  com.google.common.collect.Sets.SetView union(final Set set1, final Set set2);

    /**
     * 交集
     */
    public static  com.google.common.collect.Sets.SetView intersection(final Set set1, final Set set2);

    /**
     * 差集
     */
    public static  com.google.common.collect.Sets.SetView difference(final Set set1, final Set set2);

    /**
     * 对等差分
     * 给出两个集合 (如集合 A = {1, 2, 3} 和集合 B = {2, 3, 4}),
     * 而数学术语 "对等差分" 的集合就是指由所有只在两个集合其中之一的元素组成的集合(A △ B = C = {1, 4})
     */
    public static  com.google.common.collect.Sets.SetView symmetricDifference(
            final Set set1, final Set set2);

    /**
     * 过滤
     */
    // TODO(kevinb): how to omit that last sentence when building GWT javadoc?
    public static  Set filter(Set unfiltered, com.google.common.base.Predicate predicate);
    public static  SortedSet filter(SortedSet unfiltered, com.google.common.base.Predicate predicate);
    @GwtIncompatible // NavigableSet
    @SuppressWarnings("unchecked")
    public static  NavigableSet filter(
            NavigableSet unfiltered, com.google.common.base.Predicate predicate);

    /**
     * 对Set做笛卡尔操作
     *
     * 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}
     */
    public static  Set> cartesianProduct(List> sets);
    @SafeVarargs
    public static  Set> cartesianProduct(Set... sets) {
        return cartesianProduct(Arrays.asList(sets));
    }


    /**
     *
     * 返回Set的所有可能子集的集合。
     * 例如 powerSet(ImmutableSet.of(1, 2))} returns the set {@code {{}, {1}, {2}, {1, 2}}}.
     */
    @GwtCompatible(serializable = false)
    public static  Set> powerSet(Set set) {
        return new com.google.common.collect.Sets.PowerSet(set);
    }


    /**
     * 返回大小为size的Set的所有子集的集合
     * 例如 combinations(ImmutableSet.of(1, 2, 3), 2)} returns the set {@code {{1, 2}, {1, 3}, {2, 3}}}.
     */
    @Beta
    public static  Set> combinations(Set set, final int size);


    /**
     * 返回一个不可修改的NavigableSet
     */
    public static  NavigableSet unmodifiableNavigableSet(NavigableSet set);

    /**
     * 返回一个同步的(线程安全的)NavigableSet
     */
    @GwtIncompatible // NavigableSet
    public static  NavigableSet synchronizedNavigableSet(NavigableSet navigableSet) {
        return Synchronized.navigableSet(navigableSet);
    }


    /**
     * 获取范围内的Set
     */
    @Beta
    @GwtIncompatible // NavigableSet
    public static > NavigableSet subSet(
            NavigableSet set, Range range);
}

3.5 Maps

public final class Maps {

    /**
     * 创建ImmutableMap -- 不可以修改的Map
     */
    @GwtCompatible(serializable = true)
    public static , V> ImmutableMap immutableEnumMap(
            Map map);

    /**
     * 创建Collector
     */
    public static , V> Collector> toImmutableEnumMap(
            java.util.function.Function keyFunction,
            java.util.function.Function valueFunction);
    public static , V> Collector> toImmutableEnumMap(
            java.util.function.Function keyFunction,
            java.util.function.Function valueFunction,
            BinaryOperator mergeFunction);

    /**
     * 创建HashMap
     */
    public static  HashMap newHashMap();
    public static  HashMap newHashMap(Map map);

    /**
     * 创建LinkedHashMap
     */
    public static  LinkedHashMap newLinkedHashMap();
    public static  LinkedHashMap newLinkedHashMap(Map map);

    /**
     * 构造一个期望长度为estimatedSize的LinkedHashMap实例
     */
    public static  LinkedHashMap newLinkedHashMapWithExpectedSize(int expectedSize);

    /**
     * ConcurrentMap -- 是一个能够支持并发访问的java.util.map集合
     */
    public static  ConcurrentMap newConcurrentMap();

    /**
     * TreeMap
     */
    public static  TreeMap newTreeMap();
    public static  TreeMap newTreeMap(SortedMap map);
    public static  TreeMap newTreeMap(@Nullable Comparator comparator);

    /**
     * 创建一个EnumMap
     */
    public static , V> EnumMap newEnumMap(Class type);
    public static , V> EnumMap newEnumMap(Map map);

    /**
     * 创建一个空的Map
     */
    public static  IdentityHashMap newIdentityHashMap() {
        return new IdentityHashMap<>();
    }

    /**
     * 差集
     */
    @SuppressWarnings("unchecked")
    public static  MapDifference difference(
            Map left, Map right);
    public static  MapDifference difference(
            Map left,
            Map right,
            Equivalence valueEquivalence);
    public static  SortedMapDifference difference(
            SortedMap left, Map right);

    /**
     * 转换为Map
     */
    public static  Map asMap(Set set, Function function);
    /**
     * 转换为SortedMap
     */
    public static  SortedMap asMap(SortedSet set, Function function);
    /**
     * 转换为NavigableMap
     */
    @GwtIncompatible // NavigableMap
    public static  NavigableMap asMap(
            NavigableSet set, Function function);


    /**
     * value做相应的转换之后,生成ImmutableMap
     */
    public static  ImmutableMap toMap(
            Iterable keys, Function valueFunction);
    public static  ImmutableMap toMap(
            Iterator keys, Function valueFunction);

    /**
     * key做相应的转换之后,生成ImmutableMap
     */
    @CanIgnoreReturnValue
    public static  ImmutableMap uniqueIndex(
            Iterable values, Function keyFunction);
    @CanIgnoreReturnValue
    public static  ImmutableMap uniqueIndex(
            Iterator values, Function keyFunction);

    /**
     * 属性文件里面读到的内容Properties转换为ImmutableMap
     */
    @GwtIncompatible // java.util.Properties
    public static ImmutableMap fromProperties(Properties properties);

    /**
     * 生成不可以修改的Entry
     */
    @GwtCompatible(serializable = true)
    public static  Entry immutableEntry(@Nullable K key, @Nullable V value);


    /**
     * BiMapConverter
     */
    public static  Converter asConverter(final BiMap bimap);

    /**
     * 线程安全的BiMap
     */
    public static  BiMap synchronizedBiMap(BiMap bimap);

    /**
     * 不可以修改的BiMap
     */
    public static  BiMap unmodifiableBiMap(BiMap bimap);


    /**
     * 转换值
     */
    public static  Map transformValues(
            Map fromMap, Function function);
    public static  SortedMap transformValues(
            SortedMap fromMap, Function function);
    @GwtIncompatible // NavigableMap
    public static  NavigableMap transformValues(
            NavigableMap fromMap, Function function);

    /**
     * 转换
     */
    public static  Map transformEntries(
            Map fromMap, EntryTransformer transformer);
    public static  SortedMap transformEntries(
            SortedMap fromMap, EntryTransformer transformer);
    @GwtIncompatible // NavigableMap
    public static  NavigableMap transformEntries(
            final NavigableMap fromMap, EntryTransformer transformer);


    @GwtIncompatible // NavigableMap
    private static class TransformedEntriesNavigableMap
            extends TransformedEntriesSortedMap implements NavigableMap {

        TransformedEntriesNavigableMap(
                NavigableMap fromMap, EntryTransformer transformer) {
            super(fromMap, transformer);
        }

        @Override
        public Entry ceilingEntry(K key) {
            return transformEntry(fromMap().ceilingEntry(key));
        }

        @Override
        public K ceilingKey(K key) {
            return fromMap().ceilingKey(key);
        }

        @Override
        public NavigableSet descendingKeySet() {
            return fromMap().descendingKeySet();
        }

        @Override
        public NavigableMap descendingMap() {
            return transformEntries(fromMap().descendingMap(), transformer);
        }

        @Override
        public Entry firstEntry() {
            return transformEntry(fromMap().firstEntry());
        }

        @Override
        public Entry floorEntry(K key) {
            return transformEntry(fromMap().floorEntry(key));
        }

        @Override
        public K floorKey(K key) {
            return fromMap().floorKey(key);
        }

        @Override
        public NavigableMap headMap(K toKey) {
            return headMap(toKey, false);
        }

        @Override
        public NavigableMap headMap(K toKey, boolean inclusive) {
            return transformEntries(fromMap().headMap(toKey, inclusive), transformer);
        }

        @Override
        public Entry higherEntry(K key) {
            return transformEntry(fromMap().higherEntry(key));
        }

        @Override
        public K higherKey(K key) {
            return fromMap().higherKey(key);
        }

        @Override
        public Entry lastEntry() {
            return transformEntry(fromMap().lastEntry());
        }

        @Override
        public Entry lowerEntry(K key) {
            return transformEntry(fromMap().lowerEntry(key));
        }

        @Override
        public K lowerKey(K key) {
            return fromMap().lowerKey(key);
        }

        @Override
        public NavigableSet navigableKeySet() {
            return fromMap().navigableKeySet();
        }

        @Override
        public Entry pollFirstEntry() {
            return transformEntry(fromMap().pollFirstEntry());
        }

        @Override
        public Entry pollLastEntry() {
            return transformEntry(fromMap().pollLastEntry());
        }

        @Override
        public NavigableMap subMap(
                K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
            return transformEntries(
                    fromMap().subMap(fromKey, fromInclusive, toKey, toInclusive), transformer);
        }

        @Override
        public NavigableMap subMap(K fromKey, K toKey) {
            return subMap(fromKey, true, toKey, false);
        }

        @Override
        public NavigableMap tailMap(K fromKey) {
            return tailMap(fromKey, true);
        }

        @Override
        public NavigableMap tailMap(K fromKey, boolean inclusive) {
            return transformEntries(fromMap().tailMap(fromKey, inclusive), transformer);
        }

        private @Nullable Entry transformEntry(@Nullable Entry entry) {
            return (entry == null) ? null : Maps.transformEntry(transformer, entry);
        }

        @Override
        protected NavigableMap fromMap() {
            return (NavigableMap) super.fromMap();
        }
    }

    static  Predicate> keyPredicateOnEntries(Predicate keyPredicate) {
        return compose(keyPredicate, Maps.keyFunction());
    }

    static  Predicate> valuePredicateOnEntries(Predicate valuePredicate) {
        return compose(valuePredicate, Maps.valueFunction());
    }

    /**
     * 根据key过滤
     */
    public static  Map filterKeys(
            Map unfiltered, final Predicate keyPredicate);
    public static  SortedMap filterKeys(
            SortedMap unfiltered, final Predicate keyPredicate);
    @GwtIncompatible // NavigableMap
    public static  NavigableMap filterKeys(
            NavigableMap unfiltered, final Predicate keyPredicate);
    public static  BiMap filterKeys(
            BiMap unfiltered, final Predicate keyPredicate);

    /**
     * 根据值过滤
     */
    public static  Map filterValues(
            Map unfiltered, final Predicate valuePredicate);
    public static  SortedMap filterValues(
            SortedMap unfiltered, final Predicate valuePredicate);
    @GwtIncompatible // NavigableMap
    public static  NavigableMap filterValues(
            NavigableMap unfiltered, final Predicate valuePredicate);
    public static  BiMap filterValues(
            BiMap unfiltered, final Predicate valuePredicate);

    /**
     * 过滤
     */
    public static  Map filterEntries(
            Map unfiltered, Predicate> entryPredicate);
    public static  SortedMap filterEntries(
            SortedMap unfiltered, Predicate> entryPredicate);
    @GwtIncompatible // NavigableMap
    public static  NavigableMap filterEntries(
            NavigableMap unfiltered, Predicate> entryPredicate);
    public static  BiMap filterEntries(
            BiMap unfiltered, Predicate> entryPredicate);

    /**
     * 返回一个不可修改的NavigableMap
     */
    @GwtIncompatible // NavigableMap
    public static  NavigableMap unmodifiableNavigableMap(
            NavigableMap map);


    /**
     * 返回一个同步的(线程安全的)NavigableMap
     */
    @GwtIncompatible // NavigableMap
    public static  NavigableMap synchronizedNavigableMap(
            NavigableMap navigableMap);


    /**
     * key范围内的Map
     */
    @Beta
    @GwtIncompatible // NavigableMap
    public static , V> NavigableMap subMap(
            NavigableMap map, Range range);
}

3.6 Queues

public final class Queues {

    /**
     * 创建ArrayBlockingQueue
     */
    @GwtIncompatible // ArrayBlockingQueue
    public static  ArrayBlockingQueue newArrayBlockingQueue(int capacity);
    // ArrayDeque

    /**
     * 创建ArrayDeque
     */
    public static  ArrayDeque newArrayDeque();

    /**
     * 创建ArrayDeque
     */
    public static  ArrayDeque newArrayDeque(Iterable elements);

    // ConcurrentLinkedQueue

    /** 创建ConcurrentLinkedQueue */
    @GwtIncompatible // ConcurrentLinkedQueue
    public static  ConcurrentLinkedQueue newConcurrentLinkedQueue();

    /**
     * 创建ConcurrentLinkedQueue
     */
    @GwtIncompatible // ConcurrentLinkedQueue
    public static  ConcurrentLinkedQueue newConcurrentLinkedQueue(
            Iterable elements);

    // LinkedBlockingDeque

    /**
     * LinkedBlockingDeque
     */
    @GwtIncompatible // LinkedBlockingDeque
    public static  LinkedBlockingDeque newLinkedBlockingDeque();

    /**
     * LinkedBlockingDeque
     */
    @GwtIncompatible // LinkedBlockingDeque
    public static  LinkedBlockingDeque newLinkedBlockingDeque(int capacity);

    /**
     * LinkedBlockingDeque
     */
    @GwtIncompatible // LinkedBlockingDeque
    public static  LinkedBlockingDeque newLinkedBlockingDeque(Iterable elements);

    // LinkedBlockingQueue

    /** LinkedBlockingQueue */
    @GwtIncompatible // LinkedBlockingQueue
    public static  LinkedBlockingQueue newLinkedBlockingQueue();

    /**
     * LinkedBlockingQueue
     */
    @GwtIncompatible // LinkedBlockingQueue
    public static  LinkedBlockingQueue newLinkedBlockingQueue(int capacity);

    /**
     * LinkedBlockingQueue
     */
    @GwtIncompatible // LinkedBlockingQueue
    public static  LinkedBlockingQueue newLinkedBlockingQueue(Iterable elements);


    /**
     * PriorityBlockingQueue
     */
    @GwtIncompatible // PriorityBlockingQueue
    public static  PriorityBlockingQueue newPriorityBlockingQueue();

    /**
     * PriorityBlockingQueue
     */
    @GwtIncompatible // PriorityBlockingQueue
    public static  PriorityBlockingQueue newPriorityBlockingQueue(
            Iterable elements);

    // PriorityQueue

    /**
     * PriorityQueue
     */
    public static  PriorityQueue newPriorityQueue();

    /**
     * PriorityQueue
     */
    public static  PriorityQueue newPriorityQueue(
            Iterable elements);

    // SynchronousQueue

    /** SynchronousQueue 同步Queue,线程安全 */
    @GwtIncompatible // SynchronousQueue
    public static  SynchronousQueue newSynchronousQueue();

    /**
     * 一次性的从BlockingQueue获取多少个数据
     */
    @Beta
    @CanIgnoreReturnValue
    @GwtIncompatible // BlockingQueue
    @SuppressWarnings("GoodTime") // should accept a java.time.Duration
    public static  int drain(
            BlockingQueue q,
            Collection buffer,
            int numElements,
            long timeout,
            TimeUnit unit)
            throws InterruptedException;

    /**
     * 从BlockingQueue里面获取数据,和drain的区别就是当有异常的时候也会停止获取
     */
    @Beta
    @CanIgnoreReturnValue
    @GwtIncompatible // BlockingQueue
    @SuppressWarnings("GoodTime") // should accept a java.time.Duration
    public static  int drainUninterruptibly(
            BlockingQueue q,
            Collection buffer,
            int numElements,
            long timeout,
            TimeUnit unit);

    /**
     * 获取同步Queue, 同步Queue是线程安全的
     */
    public static  Queue synchronizedQueue(Queue queue);

    /**
     * 获取同步的Deque,Deque是双端队列
     */
    public static  Deque synchronizedDeque(Deque deque);
}

3.7 Multisets

public final class Multisets {

    /**
     * 用于生成一个Collector,T代表流中的一个一个元素,R代表最终的结果。参考Collector.of()的实现
     */
    public static > Collector toMultiset(
            java.util.function.Function elementFunction,
            java.util.function.ToIntFunction countFunction,
            java.util.function.Supplier multisetSupplier);

    /**
     * 转换为不可以修改的Multiset
     */
    public static  Multiset unmodifiableMultiset(Multiset multiset);

    /**
     * 转换为不可以修改的Multiset
     */
    @Deprecated
    public static  Multiset unmodifiableMultiset(ImmutableMultiset multiset);

    /**
     * 转换为不可以修改的SortedMultiset
     */
    @Beta
    public static  SortedMultiset unmodifiableSortedMultiset(SortedMultiset sortedMultiset);

    /**
     * Returns an immutable multiset entry with the specified element and count. The entry will be
     * serializable if {@code e} is.
     *
     * @param e the element to be associated with the returned entry
     * @param n the count to be associated with the returned entry
     * @throws IllegalArgumentException if {@code n} is negative
     */
    public static  Multiset.Entry immutableEntry(@Nullable E e, int n) {
        return new com.google.common.collect.Multisets.ImmutableEntry(e, n);
    }

    /**
     * 过滤
     */
    @Beta
    public static  Multiset filter(Multiset unfiltered, Predicate predicate);

    /**
     * 交集
     */
    public static  Multiset intersection(
            final Multiset multiset1, final Multiset multiset2);

    /**
     * 合集
     */
    @Beta
    public static  Multiset sum(
            final Multiset multiset1, final Multiset multiset2);

    /**
     * 差集
     */
    @Beta
    public static  Multiset difference(
            final Multiset multiset1, final Multiset multiset2);

    /**
     * 对任意o,如果subMultiset.count(o)<=superMultiset.count(o),返回true
     * 和containsAll()是有区别的,containsAll是指包含所有不重复的元素。举两个例子
     *
     * Multiset multiset1 = HashMultiset.create();
     * multiset1.add("a", 2);
     * multiset1.add("b");
     *
     * Multiset multiset2 = HashMultiset.create();
     * multiset2.add("a", 5);
     *
     * multiset1.containsAll(multiset2); // 返回true;因为包含了所有不重复元素,
     *
     * Multisets.containsOccurrences(multiset1, multiset2); // returns false
     */
    @CanIgnoreReturnValue
    public static boolean containsOccurrences(Multiset superMultiset, Multiset subMultiset);

    /**
     * 修改multisetToModify,以保证任意o都符合multisetToModify.count(o)<=multisetToRetain.count(o)
     */
    @CanIgnoreReturnValue
    public static boolean retainOccurrences(
            Multiset multisetToModify, Multiset multisetToRetain);

    /**
     * 对occurrencesToRemove中的重复元素,仅在multisetToModify中删除相同个数。
     * Multiset multiset1 = HashMultiset.create();
     * multiset1.add("a", 2);
     *
     * Multiset multiset2 = HashMultiset.create();
     * multiset2.add("a", 5);
     *
     * multiset2.removeOccurrences(multiset1); // multiset2 现在包含3个"a"
     */
    @CanIgnoreReturnValue
    public static boolean removeOccurrences(
            Multiset multisetToModify, Iterable occurrencesToRemove);
    @CanIgnoreReturnValue
    public static boolean removeOccurrences(
            Multiset multisetToModify, Multiset occurrencesToRemove);

    /**
     * 返回Multiset的不可变拷贝,并将元素按重复出现的次数做降序排列
     */
    @Beta
    public static  ImmutableMultiset copyHighestCountFirst(Multiset multiset);
}

3.8 Multimaps

public final class Multimaps {

    /**
     * 用于生成一个Collector,T代表流中的一个一个元素,R代表最终的结果。参考Collector.of()的实现
     */
    @Beta
    public static > Collector toMultimap(
            java.util.function.Function keyFunction,
            java.util.function.Function valueFunction,
            java.util.function.Supplier multimapSupplier);

    /**
     * 用于生成一个Collector,T代表流中的一个一个元素,R代表最终的结果。参考Collector.of()的实现
     */
    @Beta
    public static > Collector flatteningToMultimap(
            java.util.function.Function keyFunction,
            java.util.function.Function> valueFunction,
            java.util.function.Supplier multimapSupplier);

    /**
     * 生成Multimap
     */
    public static  Multimap newMultimap(
            Map> map, final Supplier> factory);

    /**
     * 生成ListMultimap
     */
    public static  ListMultimap newListMultimap(
            Map> map, final Supplier> factory);

    /**
     * 生成SetMultimap
     */
    public static  SetMultimap newSetMultimap(
            Map> map, final Supplier> factory);


    /**
     * 生成SortedSetMultimap
     */
    public static  SortedSetMultimap newSortedSetMultimap(
            Map> map, final Supplier> factory);


    /**
     * 反转Multimap
     */
    @CanIgnoreReturnValue
    public static > M invertFrom(
            Multimap source, M dest);

    /**
     * 生成同步Multimap -- 线程安全
     */
    public static  Multimap synchronizedMultimap(Multimap multimap);

    /**
     * 生成不可以修改的Multimap
     */
    public static  Multimap unmodifiableMultimap(Multimap delegate);
    @Deprecated
    public static  Multimap unmodifiableMultimap(ImmutableMultimap delegate);


    /**
     * 生成同步SetMultimap -- 线程安全
     */
    public static  SetMultimap synchronizedSetMultimap(SetMultimap multimap);

    /**
     * 生成不可以修改的SetMultimap
     */
    public static  SetMultimap unmodifiableSetMultimap(SetMultimap delegate);
    @Deprecated
    public static  SetMultimap unmodifiableSetMultimap(
            ImmutableSetMultimap delegate);

    /**
     * 生成同步SortedSetMultimap -- 线程安全
     */
    public static  SortedSetMultimap synchronizedSortedSetMultimap(
            SortedSetMultimap multimap);

    /**
     * 生成不可以修改的SortedSetMultimap
     */
    public static  SortedSetMultimap unmodifiableSortedSetMultimap(
            SortedSetMultimap delegate);

    /**
     * 生成同步的ListMultimap -- 线程安全
     */
    public static  ListMultimap synchronizedListMultimap(ListMultimap multimap);

    /**
     * 生成不可以修改的ListMultimap
     */
    public static  ListMultimap unmodifiableListMultimap(ListMultimap delegate);
    @Deprecated
    public static  ListMultimap unmodifiableListMultimap(
            ImmutableListMultimap delegate);

    /**
     * 生成不可修改的Collection
     */
    private static  Collection unmodifiableValueCollection(Collection collection);

    /**
     * 生成不可修改的Collection
     */
    private static  Collection> unmodifiableEntries(
            Collection> entries);

    /**
     * ListMultimap转换为Map
     */
    @Beta
    @SuppressWarnings("unchecked")
    // safe by specification of ListMultimap.asMap()
    public static  Map> asMap(ListMultimap multimap);

    /**
     * SetMultimap转换为Map
     */
    @Beta
    @SuppressWarnings("unchecked")
    // safe by specification of SetMultimap.asMap()
    public static  Map> asMap(SetMultimap multimap);

    /**
     * SortedSetMultimap转换为Map
     */
    @Beta
    @SuppressWarnings("unchecked")
    // safe by specification of SortedSetMultimap.asMap()
    public static  Map> asMap(SortedSetMultimap multimap);

    /**
     * Multimap转换为Map
     */
    @Beta
    public static  Map> asMap(Multimap multimap);

    /**
     * Map转换为SetMultimap
     */
    public static  SetMultimap forMap(Map map);

    /**
     * 对Value值做转换
     */
    public static  Multimap transformValues(
            Multimap fromMultimap, final Function function);
    public static  ListMultimap transformValues(
            ListMultimap fromMultimap, final Function function);

    /**
     * 对Entry值做转换
     */
    public static  Multimap transformEntries(
            Multimap fromMap, EntryTransformer transformer);
    public static  ListMultimap transformEntries(
            ListMultimap fromMap, EntryTransformer transformer);

    /**
     *
     * 按照共同的特定属性,组装成ImmutableListMultimap
     *
     * ImmutableSet digits = ImmutableSet.of("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine");
     * Function lengthFunction = new Function() {
     *     public Integer apply(String string) {
     *         return string.length();
     *     }
     * };
     *
     * ImmutableListMultimap digitsByLength= Multimaps.index(digits, lengthFunction);
     * /*
     * *  digitsByLength maps:
     * *  3 => {"one", "two", "six"}
     * *  4 => {"zero", "four", "five", "nine"}
     * *  5 => {"three", "seven", "eight"}
     *
     */
    public static  ImmutableListMultimap index(
            Iterable values, Function keyFunction);
    public static  ImmutableListMultimap index(
            Iterator values, Function keyFunction);


    /**
     * 根据key过滤
     */
    public static  SetMultimap filterKeys(
            SetMultimap unfiltered, final Predicate keyPredicate);
    public static  ListMultimap filterKeys(
            ListMultimap unfiltered, final Predicate keyPredicate);

    /**
     * 根据值过滤
     */
    public static  Multimap filterValues(
            Multimap unfiltered, final Predicate valuePredicate);
    public static  SetMultimap filterValues(
            SetMultimap unfiltered, final Predicate valuePredicate);

    /**
     * 根据Entry过滤
     */
    public static  Multimap filterEntries(
            Multimap unfiltered, Predicate> entryPredicate);
    public static  SetMultimap filterEntries(
            SetMultimap unfiltered, Predicate> entryPredicate);
}

3.9 Tables

public final class Tables {

    /**
     * 用于生成一个Collector,T代表流中的一个一个元素,R代表最终的结果。参考Collector.of()的实现
     */
    @Beta
    public static > Collector toTable(
            java.util.function.Function rowFunction,
            java.util.function.Function columnFunction,
            java.util.function.Function valueFunction,
            java.util.function.Supplier tableSupplier);
    public static > Collector toTable(
            java.util.function.Function rowFunction,
            java.util.function.Function columnFunction,
            java.util.function.Function valueFunction,
            BinaryOperator mergeFunction,
            java.util.function.Supplier tableSupplier);

    /**
     * 生成一个单元格对象
     */
    public static  Cell immutableCell(
            @Nullable R rowKey, @Nullable C columnKey, @Nullable V value);

    /**
     * 允许你把Table转置成Table Table transpose(Table table);

    /**
     * 允许你指定Table用什么样的map实现行和列
     */
    @Beta
    public static  Table newCustomTable(
            Map> backingMap, Supplier> factory);

    /**
     * 对value做转换
     */
    @Beta
    public static  Table transformValues(
            Table fromTable, Function function);


    /**
     * 返回不可修改的Table
     */
    public static  Table unmodifiableTable(
            Table table);

    /**
     * 生成不可修改的RowSortedTable
     */
    @Beta
    public static  RowSortedTable unmodifiableRowSortedTable(
            RowSortedTable table);



    /**
     * 生成同步Table -- 线程安全
     */
    public static  Table synchronizedTable(Table table);

}

四 扩展工具类

       有时候你需要实现自己的集合扩展。也许你想要在元素被添加到列表时增加特定的行为,或者你想实现一个Iterable,其底层实际上是遍历数据库查询的结果集。Guava为你,也为我们自己提供了若干工具方法,以便让类似的工作变得更简单。(毕竟,我们自己也要用这些工具扩展集合框架。)

4.1 Forwarding装饰器

       针对所有类型的集合接口,Guava都提供了Forwarding抽象类以简化装饰者模式的使用。Forwarding抽象类定义了一个抽象方法:delegate(),你可以覆盖这个方法来返回被装饰对象。所有其他方法都会直接委托给delegate()。例如说:ForwardingList.get(int)实际上执行了delegate().get(int)。

       通过创建ForwardingXXX的子类并实现delegate()方法,可以选择性地覆盖子类的方法来增加装饰功能,而不需要自己委托每个方法。

我们讲的更加直接一点就是,通过delegate()返回一个委托对象,这样我们可以对委托对象的一些方法的前后做一些我们自己的操作。

       Forwarding装饰器对应的类有很多,我们随便列出几个比如:ForwardingList(托管List的一些方法)、ForwardingMap(托管Map的一些方法)、ForwardingDeque(托管Deque的一些方法)等等。

       我们以ForwardingList来举一个例子,让大家明白Forwarding装饰器的使用。自定义ListWithDefault继承ForwardingList实现一个从List里面获取数据的时候如果为空则用一个默认值代替。当然实际使用过程中,大家需要根据不同的场讲做不同的变换。

import java.util.*;
import com.google.common.collect.*;

public class ListWithDefault extends ForwardingList {
    final E defaultValue;
    final List delegate;

    ListWithDefault(List delegate, E defaultValue) {
        this.delegate = delegate;
        this.defaultValue = defaultValue;
    }
    @Override protected List delegate() {
        return delegate;
    }
    @Override public E get(int index) {
        E v = super.get(index);
        return (v == null ? defaultValue : v);
    }
    @Override public Iterator iterator() {
        final Iterator iter = super.iterator();
        return new ForwardingIterator() {
            @Override protected Iterator delegate() {
                return iter;
            }
            @Override public E next() {
                E v = super.next();
                return (v == null ? defaultValue : v); 
            }
        };
    }
}

4.2 PeekingIterator

       Iterators提供一个Iterators.peekingIterator(Iterator)方法,来把Iterator包装为PeekingIterator,这是Iterator的子类,它能让你事先窥视[peek()]到下一次调用next()返回的元素。

PeekingIterator相对Iterator多了一个函数peek()函数。peek()让我们可以提前看到下一个元素。

       关于PeekingIterator的使用举个例子,复制一个List,并去除连续的重复元素。

List result = Lists.newArrayList();
PeekingIterator iter = Iterators.peekingIterator(source.iterator());
while (iter.hasNext()) {
    E current = iter.next();
    while (iter.hasNext() && iter.peek().equals(current)) {
        //跳过重复的元素
        iter.next();
    }
    result.add(current);
}

4.3 AbstractIterator

       实现你自己的Iterator,AbstractIterator提供了一个abstract computeNext()函数,让我们可以介入next()函数的获取。当然到没有元素的时候记得调用endOfData();

       关于AbstractIterator的使用,我们也从网上找到一个例子,如下,我们要包装一个iterator以跳过空值。

public static Iterator skipNulls(final Iterator in) {
    return new AbstractIterator() {
        protected String computeNext() {
            while (in.hasNext()) {
                String s = in.next();
                if (s != null) {
                    return s;
                }
            }
            return endOfData();
        }
    };
}

4.5 AbstractSequentialIterator

       AbstractSequentialIterator可以看做是迭代器的另一种实现方式。AbstractSequentialIterator的源码也很简单,我们可以一起来看下,源码如下

public abstract class AbstractSequentialIterator extends UnmodifiableIterator {
    private @Nullable T nextOrNull;

    /**
     * 我们需要提供第一个元素
     */
    protected AbstractSequentialIterator(@Nullable T firstOrNull) {
        this.nextOrNull = firstOrNull;
    }

    /**
     * 我们需要实现的方法
     */
    @Nullable
    protected abstract T computeNext(T previous);

    /**
     * 是否有下一个元素
     */
    @Override
    public final boolean hasNext() {
        return nextOrNull != null;
    }

    /**
     * 在调用next()方法获取next元素之后,又通过computeNext()方法把接下来的一个元素给算出来了
     */
    @Override
    public final T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        try {
            return nextOrNull;
        } finally {
            nextOrNull = computeNext(nextOrNull);
        }
    }
}

       通过源码的阅读,AbstractSequentialIterator给到我们的就是通过指定第一个元素之后,我们在根据computeNext()函数依据某种规则产生下一个元素。

       我们用一个例子来说明AbstractSequentialIterator的使用,每一个数都是前一个数的两倍。

        Iterator powersOfTwo = new AbstractSequentialIterator(1) { // 注意初始值1!
            protected Integer computeNext(Integer previous) {
                // 下一个数是前数的两倍,一直到2的3次方
                return (previous == 1 << 3) ? null : previous * 2;
            }
        };

你可能感兴趣的:(Google Guava 集合(Collections))