新集合类型
1. Multiset
Guava 提供了一个新的 Set 类型 Multiset,它可以多次添加相等的元素到 Set 集合里去。下面先看一下该集合中独特的方法:
/**
* 返回集合元素的总个数(包括重复的元素)
*/
int size();
/**
* 返回某个元素在集合中出现的次数
*/
int count(@CompatibleWith("E") @CheckForNull Object element);
/**
* 添加多个给定元素,比如multiset.add("a", 2)表示添加两个a元素,返回该元素在添加前的个数
*/
int add(@ParametricNullness E element, int occurrences);
/**
* 减少多个给定元素,比如multiset.remove("a", 2)表示删除两个a元素,返回该元素在删除前的个数
*/
int remove(@CompatibleWith("E") @CheckForNull Object element, int occurrences);
/**
* 设置给定元素在集合中的个数(不能为负数),忽略之前该元素的个数,返回该元素在操作前的个数
*/
int setCount(@ParametricNullness E element, int count);
/**
* Multiset中不重复元素的集合,返回类型为JDK中的Set类型
*/
Set<E> elementSet();
/**
* 和Map的entrySet类似,返回的Entry接口提供了getElement获取元素,getCount获取该元素的个数
*/
Set<Entry<E>> entrySet();
/**
* 遍历Multiset集合,ObjIntConsumer接收两个入参,第一个为元素,第二个为该元素个数
*/
default void forEachEntry(ObjIntConsumer<? super E> action)
Guava 提供了多种 Multiset 的实现类,大部分都是和 JDK 中的 Set 类一一对应,具体如下图:
2. Multimap
Guava 提供的 Multimap 可以很容易地把一个键映射到多个值,代替了原来 JDK 中笨拙的 Map
/**
* 返回键值对的个数,如果一个键映射了多个值则表示多个键值对
*/
int size();
/**
* 添加元素
*/
boolean putAll(@ParametricNullness K key, Iterable<? extends V> values);
/**
* 替换指定键对应的所有值元素,如果values为空,相当于删除该键
* 返回替换之前的值元素
*/
Collection<V> replaceValues(@ParametricNullness K key, Iterable<? extends V> values);
/**
* 获取指定键对应的所有值元素
*/
Collection<V> get(@ParametricNullness K key);
/**
* 获取所有键对应的值元素集合,不会过滤重复的值
*/
Collection<V> values();
/**
* 返回包含所有键值对的视图集合
*/
Collection<Entry<K, V>> entries();
/**
* 遍历所有键值对,重复键对应的多个不同值会被多次遍历
*/
default void forEach(BiConsumer<? super K, ? super V> action)
/**
* 返回Map视图,注意Collection有可能为空
*/
Map<K, Collection<V>> asMap();
Guava 也提供了多种 Multimap 的实现类,具体如下图:
3. BiMap
BiMap 是特殊的 Map 类型,提供了 key 和 value 双向关联的数据结构,这样即可以通过 key 获取 value 也可以通过 value 来获取 key。BiMap 里面 key 和 value 都是唯一不重复的。常用方法如下:
/**
* 反转键值对
*/
BiMap<V, K> inverse();
4. Table
Guava 提供的 Table 集合类型可以用来支持 Map
/**
* 指定行,列键对应的值是否存在
*/
boolean contains(
@CompatibleWith("R") @CheckForNull Object rowKey,
@CompatibleWith("C") @CheckForNull Object columnKey);
/**
* 指定行键是否存在
*/
boolean containsRow(@CompatibleWith("R") @CheckForNull Object rowKey);
/**
* 指定列键是否存在
*/
boolean containsColumn(@CompatibleWith("C") @CheckForNull Object columnKey);
/**
* 指定值是否存在,不关心所属的行、列键
*/
boolean containsValue(@CompatibleWith("V") @CheckForNull Object value);
/**
* 获取指定行,列键对应的值
*/
V get(
@CompatibleWith("R") @CheckForNull Object rowKey,
@CompatibleWith("C") @CheckForNull Object columnKey);
/**
* 填充行,列及对应的值,返回先前与行、列键关联的值
*/
V put(@ParametricNullness R rowKey, @ParametricNullness C columnKey, @ParametricNullness V value);
/**
* 删除指定行,列键对应的值,返回先前与行、列键关联的值
*/
V remove(
@CompatibleWith("R") @CheckForNull Object rowKey,
@CompatibleWith("C") @CheckForNull Object columnKey);
/**
* 指定行键对应的所有数据
*/
Map<C, V> row(@ParametricNullness R rowKey);
/**
* 指定列键对应的所有数据
*/
Map<R, V> column(@ParametricNullness C columnKey);
/**
* 返回单元格集合,用元素类型为Table.Cell<R, C, V>的Set表示Table<R, C, V>
* Cell类似于Map.Entry,但它是用行和列两个键区分的
*/
Set<Cell<R, C, V>> cellSet();
/**
* 行键集合
*/
Set<R> rowKeySet();
/**
* 列键集合
*/
Set<C> columnKeySet();
/**
* 用Map<R, Map<C, V>>表现Table<R, C, V>
*/
Map<R, Map<C, V>> rowMap();
/**
* 用Map<C, Map<R, V>>表现Table<R, C, V>
*/
Map<C, Map<R, V>> columnMap();
5. ClassToInstanceMap
ClassToInstanceMap 提供了一种用 Class 作为 Key,对应实例作为 Value 的途径。他定义了 getInstance 和 putInstance 两个方法,消除了元素类型转换的过程并保证了元素在 Map 中是类型安全的。使用该集合唯一目的就是消除类型转换过程中可能产生的错误,比如在传递参数时就可以用 ClassToInstanceMap 了。
/**
* 获取指定Class类型对应的实例
*/
<T extends B> T getInstance(Class<T> type);
/**
* 添加指定Class类型及其实例元素
*/
<T extends B> T putInstance(Class<T> type, T value);
6. EvictingQueue
EvictingQueue 是一个非阻塞队列,当尝试向队列添加新元素并且队列已满时,它会自动从队列的头部来驱逐元素。该队列对元素按照 FIFO(先进先出)进行排序。
这个数据结构在逻辑上相当于一个循环缓冲区或环形缓冲区,驱逐队列必须配置最大大小。每次将元素添加到已满队列时,队列都会自动删除其头元素。这与传统的有界队列不同,后者在元素满时会阻塞或拒绝新元素。
/**
* 创建驱逐队列
*/
public static <E> EvictingQueue<E> create(int maxSize)
/**
* 返回此队列可以接受而不发生驱逐的元素的数量;如果队列当前已满则为零
*/
public int remainingCapacity()
/**
* 将给定元素添加到此队列。如果队列当前已满,则将队列头部的元素逐出以腾出空间
* 方法永远返回true
*/
public boolean offer(E e)
public boolean add(E e)
7. MinMaxPriorityQueue
MinMaxPriorityQueue 是一个双端优先级队列,支持以 O(1) 时间复杂度访问队列的最小元素和最大元素。队列优先级由比较器确定,如果在创建时没有给出比较器,则使用元素的自然顺序。如果在队列创建时没有给出最大大小,则队列是无界的。否则,当队列大小超过最大容量时,队列会根据其比较器自动删除最大元素。
MinMaxPriorityQueue 的功能与 PriorityQueue 完全相同,可通过 peek()、poll() 和 remove() 方法操作队列的头元素,但与常规优先级队列不同的是,还提供了 peekLast、pollLast 和 removeLast 方法来操作队列中的尾元素。 如果我们只访问队列的一端,并且不使用最大大小,则此类在功能上等同于 PriorityQueue,但执行速度要慢得多。
/**
* 使用默认设置创建一个新的最小最大优先级队列:自然顺序,无最大容量
*/
public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create()
public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create(Iterable<? extends E> initialContents)
/**
* 以Builder创建一个最小最大优先级队列:通过comparator排序,最大容量为maximumSize
*/
public static <B> Builder<B> orderedBy(Comparator<B> comparator)
public static Builder<Comparable> expectedSize(int expectedSize)
public static Builder<Comparable> maximumSize(int maximumSize)
/**
* 将给定元素添加到此队列。如果此队列具有最大大小,则在添加后,队列将自动驱逐其最大的元素
*/
public boolean add(E element)
public boolean addAll(Collection<? extends E> newElements)
public boolean offer(E element)
/**
* 操作队列的最大、最小元素
*/
public E pollFirst()
public E removeFirst()
public E peekFirst()
public E pollLast()
public E removeLast()
public E peekLast()
不可变集合
不可变集合,顾名思义就是集合内容不可被修改,集合的数据项在创建时提供,并且在整个生命周期中都不可再改变,一旦不可变集合创建后,就不可以对集合里面的元素做增、删、改操作了,如果尝试去修改不可变集合则会抛出 UnsupportedOperationException 异常。
不可变集合的优势:
- 对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象
- immutable 对象在多线程环境下是线程安全,因为没有竞态条件
- 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率
下面看下 Guava 库里提供了哪些不可变集合,以及这些集合和 JDK 里面集合的关系:
Guava 提供的不可变集合 | 对应 JDK 里的集合类型 |
---|---|
ImmutableList | List |
ImmutableMap | Map |
ImmutableSortedMap | SortedMap |
ImmutableSet | Set |
ImmutableSortedSet | SortedSet |
Guava 库里面提供的每个不可变集合类都有如下三种创建方法:
调用静态方法 of 创建。
ImmutableList<String> imutableList = ImmutableList.of("a", "b");
调用静态方法 copyOf 创建,可以将对应的 JDK 集合转换为 Guava 不可变集合。
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
ImmutableList<String> imutableList = ImmutableList.copyOf(list);
调用静态方法 build 创建。
ImmutableList imutableList = ImmutableList.builder()
.add("a")
.add("b")
.build();
集合工具类
1. Collections2
```java /**
- 元素过滤,返回的集合是unfiltered的实时视图,一个的变化会影响另一个
*/
public static
Collection filter( Collection unfiltered, Predicate<? super E> predicate)
/**
- 元素转换,返回的集合是fromCollection的实时视图,一个的变化会影响另一个
*/
public staticCollection 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 staticLinkedList newLinkedList() public static LinkedList newLinkedList(Iterable<? extends E> elements)
/**
- 构造CopyOnWriteArrayList
*/
public staticCopyOnWriteArrayList 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 staticList - > partition(List
list, int size)
/**
- 反转集合
*/
public staticList reverse(List list)
```3. Maps
```java /** - 构造HashMap
*/
public static
HashMap newHashMap() public static HashMap newHashMap(Map<? extends K, ? extends V> map)
/**
- 构造LinkedHashMap
*/
public staticLinkedHashMap newLinkedHashMap()
public staticLinkedHashMap newLinkedHashMap(Map<? extends K, ? extends V> map)
/**
- 构造其他类型的Map
*/
public staticConcurrentMap newConcurrentMap()
public staticTreeMap newTreeMap()
public static, V extends @Nullable Object> EnumMap newEnumMap(Class type)
/**
- 差集
*/
public staticMapDifference difference( Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right)
/**
- 转换为Map
*/
public staticMap asMap( Set set, Function<? super K, V> function)
/**
- 将属性文件里面读到的内容转换为ImmutableMap
*/
public static ImmutableMapfromProperties(Properties properties)
/**
- 转换Map中的值
*/
public static <
MapK extends @Nullable Object, V1 extends @Nullable Object, V2 extends @Nullable Object>
transformValues(Map fromMap, Function<? super V1, V2> function)
/**
- 过滤Map中指定的键
*/
public staticMap filterKeys( Map unfiltered, final Predicate<? super K> keyPredicate)
/**
- 过滤Map中指定的值
*/
public staticMap 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 staticT[] newArray(T[] reference, int length)
/**
- 返回一个新数组,其中包含两个数组的串联内容
*/
public staticT[] 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
public static
public static
public static
public static
public static
public static
/**
- 一次性的从BlockingQueue中获取 numElements 个元素,如果不满足则等待 timeout 后超时
*/
public staticint drain( BlockingQueue q, Collection<? super E> buffer, int numElements, java.time.Duration timeout) throws InterruptedException
public static
/**
- 一次性的从BlockingQueue中获取 numElements 个元素,和drain的区别是如果在等待时被中断不抛出异常
*/
public static
int drainUninterruptibly( BlockingQueue q, Collection<? super E> buffer, int numElements, java.time.Duration timeout)
public static
<a name="F7STy"></a>
## 6. Sets
```java
/**
* 创建Set集合
*/
public static <E extends @Nullable Object> HashSet<E> newHashSet()
public static <E> Set<E> newConcurrentHashSet()
public static <E extends @Nullable Object> LinkedHashSet<E> newLinkedHashSet()
public static <E extends Comparable> TreeSet<E> newTreeSet()
public static <E extends @Nullable Object> CopyOnWriteArraySet<E> newCopyOnWriteArraySet()
public static <E extends Enum<E>> EnumSet<E> complementOf(Collection<E> collection)
/**
* 返回两个集合的并集
*/
public static <E extends @Nullable Object> SetView<E> union(
final Set<? extends E> set1, final Set<? extends E> set2)
/**
* 返回两个集合的交集
*/
public static <E extends @Nullable Object> SetView<E> intersection(
final Set<E> set1, final Set<?> set2)
/**
* 返回两个集合的查集
*/
public static <E extends @Nullable Object> SetView<E> difference(
final Set<E> set1, final Set<?> set2)
/**
* 集合元素过滤
*/
public static <E extends @Nullable Object> Set<E> filter(
Set<E> unfiltered, Predicate<? super E> predicate)
/**
* 对Set做笛卡尔操作
* 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{{a,0},{a,1},{a,2},{b,0},{b,1},{b,2}}
*/
public static <B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets)
/**
* 返回集合的所有可能子集的集合。例如{1,2}返回集合{{}, {1}, {2}, {1,2}}
*/
public static <E> Set<Set<E>> powerSet(Set<E> set)
/**
* 返回大小为size的Set的所有子集的集合
* 例如 combinations(ImmutableSet.of(1, 2, 3), 2)} 返回 {{1,2}, {1,3}, {2,3}}
*/
public static <E> Set<Set<E>> combinations(Set<E> set, final int size)
7. Iterables
/**
* 返回不可修改的迭代器
*/
public static <T extends @Nullable Object> Iterable<T> unmodifiableIterable(
final Iterable<? extends T> iterable)
/**
* 返回迭代器元素个数
*/
public static int size(Iterable<?> iterable)
/**
* 迭代器是否包含指定元素
*/
public static boolean contains(
Iterable<? extends @Nullable Object> iterable, @CheckForNull Object element)
/**
* 移除元素
*/
public static boolean removeAll(Iterable<?> removeFrom, Collection<?> elementsToRemove)
/**
* 移除满足条件的元素
*/
public static <T extends @Nullable Object> boolean removeIf(
Iterable<T> removeFrom, Predicate<? super T> predicate)
/**
* 如果两个迭代器中的所有元素相等且顺序一致,返回true
*/
public static boolean elementsEqual(Iterable<?> iterable1, Iterable<?> iterable2)
/**
* 迭代器转数组
*/
public static <T> @Nullable T[] toArray(Iterable<? extends @Nullable T> iterable, Class<T> type)
/**
* 返回指定元素在迭代器中出现的次数
*/
public static int frequency(Iterable<?> iterable, @CheckForNull Object element)
/**
* 串联迭代器
*/
public static <T extends @Nullable Object> Iterable<T> concat(
Iterable<? extends T> a, Iterable<? extends T> b)
/**
* 对迭代器做分片,size为子迭代器元素数量
*/
public static <T extends @Nullable Object> Iterable<List<T>> partition(
final Iterable<T> iterable, final int size)
/**
* 过滤出满足条件的值
*/
public static <T extends @Nullable Object> Iterable<T> filter(
final Iterable<T> unfiltered, final Predicate<? super T> retainIfTrue)
/**
* 获取迭代器指定位置的元素
*/
public static <T extends @Nullable Object> T get(Iterable<T> iterable, int position)
/**
* 返回跳过指定元素的迭代器
*/
public static <T extends @Nullable Object> Iterable<T> skip(
final Iterable<T> iterable, final int numberToSkip)