新集合类型

1. Multiset

Guava 提供了一个新的 Set 类型 Multiset,它可以多次添加相等的元素到 Set 集合里去。下面先看一下该集合中独特的方法:

  1. /**
  2. * 返回集合元素的总个数(包括重复的元素)
  3. */
  4. int size();
  5. /**
  6. * 返回某个元素在集合中出现的次数
  7. */
  8. int count(@CompatibleWith("E") @CheckForNull Object element);
  9. /**
  10. * 添加多个给定元素,比如multiset.add("a", 2)表示添加两个a元素,返回该元素在添加前的个数
  11. */
  12. int add(@ParametricNullness E element, int occurrences);
  13. /**
  14. * 减少多个给定元素,比如multiset.remove("a", 2)表示删除两个a元素,返回该元素在删除前的个数
  15. */
  16. int remove(@CompatibleWith("E") @CheckForNull Object element, int occurrences);
  17. /**
  18. * 设置给定元素在集合中的个数(不能为负数),忽略之前该元素的个数,返回该元素在操作前的个数
  19. */
  20. int setCount(@ParametricNullness E element, int count);
  21. /**
  22. * Multiset中不重复元素的集合,返回类型为JDK中的Set类型
  23. */
  24. Set<E> elementSet();
  25. /**
  26. * 和Map的entrySet类似,返回的Entry接口提供了getElement获取元素,getCount获取该元素的个数
  27. */
  28. Set<Entry<E>> entrySet();
  29. /**
  30. * 遍历Multiset集合,ObjIntConsumer接收两个入参,第一个为元素,第二个为该元素个数
  31. */
  32. default void forEachEntry(ObjIntConsumer<? super E> action)

Guava 提供了多种 Multiset 的实现类,大部分都是和 JDK 中的 Set 类一一对应,具体如下图:
Multiset.png

2. Multimap

Guava 提供的 Multimap 可以很容易地把一个键映射到多个值,代替了原来 JDK 中笨拙的 Map 或 Map 结构。下面先看一下该集合的常用方法:

  1. /**
  2. * 返回键值对的个数,如果一个键映射了多个值则表示多个键值对
  3. */
  4. int size();
  5. /**
  6. * 添加元素
  7. */
  8. boolean putAll(@ParametricNullness K key, Iterable<? extends V> values);
  9. /**
  10. * 替换指定键对应的所有值元素,如果values为空,相当于删除该键
  11. * 返回替换之前的值元素
  12. */
  13. Collection<V> replaceValues(@ParametricNullness K key, Iterable<? extends V> values);
  14. /**
  15. * 获取指定键对应的所有值元素
  16. */
  17. Collection<V> get(@ParametricNullness K key);
  18. /**
  19. * 获取所有键对应的值元素集合,不会过滤重复的值
  20. */
  21. Collection<V> values();
  22. /**
  23. * 返回包含所有键值对的视图集合
  24. */
  25. Collection<Entry<K, V>> entries();
  26. /**
  27. * 遍历所有键值对,重复键对应的多个不同值会被多次遍历
  28. */
  29. default void forEach(BiConsumer<? super K, ? super V> action)
  30. /**
  31. * 返回Map视图,注意Collection有可能为空
  32. */
  33. Map<K, Collection<V>> asMap();

Guava 也提供了多种 Multimap 的实现类,具体如下图:
Multimap.png

3. BiMap

BiMap 是特殊的 Map 类型,提供了 key 和 value 双向关联的数据结构,这样即可以通过 key 获取 value 也可以通过 value 来获取 key。BiMap 里面 key 和 value 都是唯一不重复的。常用方法如下:

  1. /**
  2. * 反转键值对
  3. */
  4. BiMap<V, K> inverse();

实现类如下图所示:
BiMap.png

4. Table

Guava 提供的 Table 集合类型可以用来支持 Map 这种数据结构。Table 类型有 rowcolumn 这两个键以及一个 value 值,可以将其想象成一个表格里面的行和列坐标,坐标对应的单元格即为值。

  1. /**
  2. * 指定行,列键对应的值是否存在
  3. */
  4. boolean contains(
  5. @CompatibleWith("R") @CheckForNull Object rowKey,
  6. @CompatibleWith("C") @CheckForNull Object columnKey);
  7. /**
  8. * 指定行键是否存在
  9. */
  10. boolean containsRow(@CompatibleWith("R") @CheckForNull Object rowKey);
  11. /**
  12. * 指定列键是否存在
  13. */
  14. boolean containsColumn(@CompatibleWith("C") @CheckForNull Object columnKey);
  15. /**
  16. * 指定值是否存在,不关心所属的行、列键
  17. */
  18. boolean containsValue(@CompatibleWith("V") @CheckForNull Object value);
  19. /**
  20. * 获取指定行,列键对应的值
  21. */
  22. V get(
  23. @CompatibleWith("R") @CheckForNull Object rowKey,
  24. @CompatibleWith("C") @CheckForNull Object columnKey);
  25. /**
  26. * 填充行,列及对应的值,返回先前与行、列键关联的值
  27. */
  28. V put(@ParametricNullness R rowKey, @ParametricNullness C columnKey, @ParametricNullness V value);
  29. /**
  30. * 删除指定行,列键对应的值,返回先前与行、列键关联的值
  31. */
  32. V remove(
  33. @CompatibleWith("R") @CheckForNull Object rowKey,
  34. @CompatibleWith("C") @CheckForNull Object columnKey);
  35. /**
  36. * 指定行键对应的所有数据
  37. */
  38. Map<C, V> row(@ParametricNullness R rowKey);
  39. /**
  40. * 指定列键对应的所有数据
  41. */
  42. Map<R, V> column(@ParametricNullness C columnKey);
  43. /**
  44. * 返回单元格集合,用元素类型为Table.Cell<R, C, V>的Set表示Table<R, C, V>
  45. * Cell类似于Map.Entry,但它是用行和列两个键区分的
  46. */
  47. Set<Cell<R, C, V>> cellSet();
  48. /**
  49. * 行键集合
  50. */
  51. Set<R> rowKeySet();
  52. /**
  53. * 列键集合
  54. */
  55. Set<C> columnKeySet();
  56. /**
  57. * 用Map<R, Map<C, V>>表现Table<R, C, V>
  58. */
  59. Map<R, Map<C, V>> rowMap();
  60. /**
  61. * 用Map<C, Map<R, V>>表现Table<R, C, V>
  62. */
  63. Map<C, Map<R, V>> columnMap();

实现类如下图所示:
Table.png

5. ClassToInstanceMap

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

  1. /**
  2. * 获取指定Class类型对应的实例
  3. */
  4. <T extends B> T getInstance(Class<T> type);
  5. /**
  6. * 添加指定Class类型及其实例元素
  7. */
  8. <T extends B> T putInstance(Class<T> type, T value);

6. EvictingQueue

EvictingQueue 是一个非阻塞队列,当尝试向队列添加新元素并且队列已满时,它会自动从队列的头部来驱逐元素。该队列对元素按照 FIFO(先进先出)进行排序。

这个数据结构在逻辑上相当于一个循环缓冲区或环形缓冲区,驱逐队列必须配置最大大小。每次将元素添加到已满队列时,队列都会自动删除其头元素。这与传统的有界队列不同,后者在元素满时会阻塞或拒绝新元素。

  1. /**
  2. * 创建驱逐队列
  3. */
  4. public static <E> EvictingQueue<E> create(int maxSize)
  5. /**
  6. * 返回此队列可以接受而不发生驱逐的元素的数量;如果队列当前已满则为零
  7. */
  8. public int remainingCapacity()
  9. /**
  10. * 将给定元素添加到此队列。如果队列当前已满,则将队列头部的元素逐出以腾出空间
  11. * 方法永远返回true
  12. */
  13. public boolean offer(E e)
  14. public boolean add(E e)

7. MinMaxPriorityQueue

MinMaxPriorityQueue 是一个双端优先级队列,支持以 O(1) 时间复杂度访问队列的最小元素和最大元素。队列优先级由比较器确定,如果在创建时没有给出比较器,则使用元素的自然顺序。如果在队列创建时没有给出最大大小,则队列是无界的。否则,当队列大小超过最大容量时,队列会根据其比较器自动删除最大元素。

MinMaxPriorityQueue 的功能与 PriorityQueue 完全相同,可通过 peek()、poll() 和 remove() 方法操作队列的头元素,但与常规优先级队列不同的是,还提供了 peekLast、pollLast 和 removeLast 方法来操作队列中的尾元素。 如果我们只访问队列的一端,并且不使用最大大小,则此类在功能上等同于 PriorityQueue,但执行速度要慢得多。

  1. /**
  2. * 使用默认设置创建一个新的最小最大优先级队列:自然顺序,无最大容量
  3. */
  4. public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create()
  5. public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create(Iterable<? extends E> initialContents)
  6. /**
  7. * 以Builder创建一个最小最大优先级队列:通过comparator排序,最大容量为maximumSize
  8. */
  9. public static <B> Builder<B> orderedBy(Comparator<B> comparator)
  10. public static Builder<Comparable> expectedSize(int expectedSize)
  11. public static Builder<Comparable> maximumSize(int maximumSize)
  12. /**
  13. * 将给定元素添加到此队列。如果此队列具有最大大小,则在添加后,队列将自动驱逐其最大的元素
  14. */
  15. public boolean add(E element)
  16. public boolean addAll(Collection<? extends E> newElements)
  17. public boolean offer(E element)
  18. /**
  19. * 操作队列的最大、最小元素
  20. */
  21. public E pollFirst()
  22. public E removeFirst()
  23. public E peekFirst()
  24. public E pollLast()
  25. public E removeLast()
  26. public E peekLast()

不可变集合

不可变集合,顾名思义就是集合内容不可被修改,集合的数据项在创建时提供,并且在整个生命周期中都不可再改变,一旦不可变集合创建后,就不可以对集合里面的元素做增、删、改操作了,如果尝试去修改不可变集合则会抛出 UnsupportedOperationException 异常。

不可变集合的优势:

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

下面看下 Guava 库里提供了哪些不可变集合,以及这些集合和 JDK 里面集合的关系:

Guava 提供的不可变集合 对应 JDK 里的集合类型
ImmutableList List
ImmutableMap Map
ImmutableSortedMap SortedMap
ImmutableSet Set
ImmutableSortedSet SortedSet

Guava 库里面提供的每个不可变集合类都有如下三种创建方法:

  • 调用静态方法 of 创建。

    1. ImmutableList<String> imutableList = ImmutableList.of("a", "b");
  • 调用静态方法 copyOf 创建,可以将对应的 JDK 集合转换为 Guava 不可变集合。

    1. List<String> list = new ArrayList<>();
    2. list.add("a");
    3. list.add("b");
    4. ImmutableList<String> imutableList = ImmutableList.copyOf(list);
  • 调用静态方法 build 创建。

    1. ImmutableList imutableList = ImmutableList.builder()
    2. .add("a")
    3. .add("b")
    4. .build();

    集合工具类

    1. Collections2

    ```java /**

    • 元素过滤,返回的集合是unfiltered的实时视图,一个的变化会影响另一个 */ public static Collection filter( Collection unfiltered, Predicate<? super E> predicate)

/**

  • 元素转换,返回的集合是fromCollection的实时视图,一个的变化会影响另一个 */
    public static Collection transform( Collection fromCollection, Function<? super F, T> function) ```

    2. Lists

    ```java /**
  • 构造ArrayList */ public static ArrayList newArrayList() public static ArrayList newArrayList(E… elements) public static ArrayList newArrayList(Iterable<? extends E> elements) public static ArrayList newArrayList(Iterator<? extends E> elements)

/**

  • 构造LinkedList */
    public static LinkedList newLinkedList() public static LinkedList newLinkedList(Iterable<? extends E> elements)

/**

  • 构造CopyOnWriteArrayList */
    public static CopyOnWriteArrayList newCopyOnWriteArrayList() public static CopyOnWriteArrayList newCopyOnWriteArrayList(Iterable<? extends E> elements)

/**

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

/**

  • 对list里面的每个元素做转换,返回的列表是fromList的转换视图;对fromList的更改将反映在返回列表中 */ public static List transform( List fromList, Function<? super F, ? extends T> function)

/**

  • 对list做分片处理,size为子列表大小 */
    public static List> partition(List list, int size)

/**

  • 反转集合 */
    public static List reverse(List list)
    ```

    3. Maps

    ```java /**
  • 构造HashMap */ public static HashMap newHashMap() public static HashMap newHashMap(Map<? extends K, ? extends V> map)

/**

  • 构造LinkedHashMap */
    public static LinkedHashMap newLinkedHashMap()
    public static LinkedHashMap newLinkedHashMap(Map<? extends K, ? extends V> map)

/**

  • 构造其他类型的Map */
    public static ConcurrentMap newConcurrentMap()
    public static TreeMap newTreeMap()
    public static , V extends @Nullable Object> EnumMap newEnumMap(Class type)

/**

  • 差集 */
    public static MapDifference difference(
    1. Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right)

/**

  • 转换为Map */
    public static Map asMap( Set set, Function<? super K, V> function)

/**

  • 将属性文件里面读到的内容转换为ImmutableMap */
    public static ImmutableMap fromProperties(Properties properties)

/**

  • 转换Map中的值 */
    public static <
    1. K extends @Nullable Object, V1 extends @Nullable Object, V2 extends @Nullable Object>
    Map transformValues(Map fromMap, Function<? super V1, V2> function)

/**

  • 过滤Map中指定的键 */
    public static Map filterKeys( Map unfiltered, final Predicate<? super K> keyPredicate)

/**

  • 过滤Map中指定的值 */
    public static Map filterValues( Map unfiltered, final Predicate<? super V> valuePredicate)

/**

  • 根据Map中的键值对进行过滤 */ public static Map filterEntries( Map unfiltered, Predicate<? super Entry> entryPredicate)
    ```

    4. ObjectArrays

    ```java /**
  • 返回指定类型、指定长度的数组 */ public static T[] newArray(Class type, int length)

/**

  • 返回给定长度的新数组,其类型与reference数组相同 */
    public static T[] newArray(T[] reference, int length)

/**

  • 返回一个新数组,其中包含两个数组的串联内容 */
    public static T[] concat(T[] first, T[] second, Class type)

/**

  • 返回一个将element前置到array的新数组 */ public static T[] concat(@ParametricNullness T element, T[] array)

/**

  • 返回一个将element追加到array的新数组 */ public static T[] concat(T[] array, @ParametricNullness T element) ```

    5. Queues

    ```java /**
  • 创建队列 */ public static ArrayBlockingQueue newArrayBlockingQueue(int capacity)

public static ArrayDeque newArrayDeque()

public static ConcurrentLinkedQueue newConcurrentLinkedQueue()

public static LinkedBlockingDeque newLinkedBlockingDeque()

public static LinkedBlockingQueue newLinkedBlockingQueue()

public static PriorityQueue newPriorityQueue()

public static PriorityBlockingQueue newPriorityBlockingQueue()

public static SynchronousQueue newSynchronousQueue()

/**

  • 一次性的从BlockingQueue中获取 numElements 个元素,如果不满足则等待 timeout 后超时 */
    public static int drain( BlockingQueue q, Collection<? super E> buffer, int numElements, java.time.Duration timeout) throws InterruptedException

public static int drain( BlockingQueue q, Collection<? super E> buffer, int numElements, long timeout, TimeUnit unit) throws InterruptedException

/**

  • 一次性的从BlockingQueue中获取 numElements 个元素,和drain的区别是如果在等待时被中断不抛出异常 */ public static int drainUninterruptibly( BlockingQueue q, Collection<? super E> buffer, int numElements, java.time.Duration timeout)

public static int drainUninterruptibly( BlockingQueue q, Collection<? super E> buffer, int numElements, long timeout, TimeUnit unit)

  1. <a name="F7STy"></a>
  2. ## 6. Sets
  3. ```java
  4. /**
  5. * 创建Set集合
  6. */
  7. public static <E extends @Nullable Object> HashSet<E> newHashSet()
  8. public static <E> Set<E> newConcurrentHashSet()
  9. public static <E extends @Nullable Object> LinkedHashSet<E> newLinkedHashSet()
  10. public static <E extends Comparable> TreeSet<E> newTreeSet()
  11. public static <E extends @Nullable Object> CopyOnWriteArraySet<E> newCopyOnWriteArraySet()
  12. public static <E extends Enum<E>> EnumSet<E> complementOf(Collection<E> collection)
  13. /**
  14. * 返回两个集合的并集
  15. */
  16. public static <E extends @Nullable Object> SetView<E> union(
  17. final Set<? extends E> set1, final Set<? extends E> set2)
  18. /**
  19. * 返回两个集合的交集
  20. */
  21. public static <E extends @Nullable Object> SetView<E> intersection(
  22. final Set<E> set1, final Set<?> set2)
  23. /**
  24. * 返回两个集合的查集
  25. */
  26. public static <E extends @Nullable Object> SetView<E> difference(
  27. final Set<E> set1, final Set<?> set2)
  28. /**
  29. * 集合元素过滤
  30. */
  31. public static <E extends @Nullable Object> Set<E> filter(
  32. Set<E> unfiltered, Predicate<? super E> predicate)
  33. /**
  34. * 对Set做笛卡尔操作
  35. * 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{{a,0},{a,1},{a,2},{b,0},{b,1},{b,2}}
  36. */
  37. public static <B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets)
  38. /**
  39. * 返回集合的所有可能子集的集合。例如{1,2}返回集合{{}, {1}, {2}, {1,2}}
  40. */
  41. public static <E> Set<Set<E>> powerSet(Set<E> set)
  42. /**
  43. * 返回大小为size的Set的所有子集的集合
  44. * 例如 combinations(ImmutableSet.of(1, 2, 3), 2)} 返回 {{1,2}, {1,3}, {2,3}}
  45. */
  46. public static <E> Set<Set<E>> combinations(Set<E> set, final int size)

7. Iterables

  1. /**
  2. * 返回不可修改的迭代器
  3. */
  4. public static <T extends @Nullable Object> Iterable<T> unmodifiableIterable(
  5. final Iterable<? extends T> iterable)
  6. /**
  7. * 返回迭代器元素个数
  8. */
  9. public static int size(Iterable<?> iterable)
  10. /**
  11. * 迭代器是否包含指定元素
  12. */
  13. public static boolean contains(
  14. Iterable<? extends @Nullable Object> iterable, @CheckForNull Object element)
  15. /**
  16. * 移除元素
  17. */
  18. public static boolean removeAll(Iterable<?> removeFrom, Collection<?> elementsToRemove)
  19. /**
  20. * 移除满足条件的元素
  21. */
  22. public static <T extends @Nullable Object> boolean removeIf(
  23. Iterable<T> removeFrom, Predicate<? super T> predicate)
  24. /**
  25. * 如果两个迭代器中的所有元素相等且顺序一致,返回true
  26. */
  27. public static boolean elementsEqual(Iterable<?> iterable1, Iterable<?> iterable2)
  28. /**
  29. * 迭代器转数组
  30. */
  31. public static <T> @Nullable T[] toArray(Iterable<? extends @Nullable T> iterable, Class<T> type)
  32. /**
  33. * 返回指定元素在迭代器中出现的次数
  34. */
  35. public static int frequency(Iterable<?> iterable, @CheckForNull Object element)
  36. /**
  37. * 串联迭代器
  38. */
  39. public static <T extends @Nullable Object> Iterable<T> concat(
  40. Iterable<? extends T> a, Iterable<? extends T> b)
  41. /**
  42. * 对迭代器做分片,size为子迭代器元素数量
  43. */
  44. public static <T extends @Nullable Object> Iterable<List<T>> partition(
  45. final Iterable<T> iterable, final int size)
  46. /**
  47. * 过滤出满足条件的值
  48. */
  49. public static <T extends @Nullable Object> Iterable<T> filter(
  50. final Iterable<T> unfiltered, final Predicate<? super T> retainIfTrue)
  51. /**
  52. * 获取迭代器指定位置的元素
  53. */
  54. public static <T extends @Nullable Object> T get(Iterable<T> iterable, int position)
  55. /**
  56. * 返回跳过指定元素的迭代器
  57. */
  58. public static <T extends @Nullable Object> Iterable<T> skip(
  59. final Iterable<T> iterable, final int numberToSkip)