<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
写在前面的话
commons-collections 包诞生的原因<small>(和 guava 库一样)</small>是对 JDK 中的集合框架的扩展。但是其功能和代码质量要稍逊于 Guava 库。
推荐使用 Guava 库。
IterableUtils 工具类
Iterable
的概念涵盖了 数组 和 集合 。所以,下述的方法可以作用于数组,而后续的 CollectionUtils 中的方法就只能作用于集合。
方法 | 说明 | 备注 |
---|---|---|
find | 循环,查找/选中 | 只会返回第一个满足条件的元素 |
forEach | 循环,执行 |
CollectionUtils 工具类
方法 | 说明 | 备注 |
---|---|---|
isEmpty | 判断,要求集合为空 |
null 也算作空 |
isNotEmpty | 判断,要求集合为非空 |
null 也算作空 |
addAll | 将参数2 中的元素,添加至参数1 中。 |
如果参数1 并未发生变化,则返回 false 。 |
isEqualCollection | 判断两个集合是否相等 | |
select | 循环遍历,查找,选出元素 | 所有符合条件的元素都将返回 原集合内容不变 |
filter | 循环遍历,查找,删除元素 | 所有符合条件的元素将被留下, 不符合的元素都将从容器中删除。 原集合内容会变。 如果原集合中至少有 1 个元素被移除,则 filter 方法返回 true 。 |
transform | 循环遍历,形变 | 原集合内容会发生变化。 |
collect | 循环遍历,形变 | 原集合内容不变,生成一个新集合 |
扩展的数据结构
Bag 接口
Bag 的行为似乎是介于 Set 和 Map 之间,向 Bag 中添加重复数据时,Bag 不会记录数据本身,而是去记录数据出现/添加的次数。
Bag 接口继承自 Collection 接口,它有两个常见实现类:
-
HashBag
-
TreeBag
Bag<Integer> b1 = new HashBag<>();
b1.add(10);
b1.add(10);
b1.add(10);
b1.add(10);
b1.add(20);
b1.getCount(10) == 4
b1.getCount(20) == 1
b1.size() == 5
b1.uniqueSet().size() == 2
注意,从 bag 中移除元素时,并非将其数显次数减一,而是类似移除 Map 中的键值对一样,将该元素及其所有出现次数都移除。
MultiSet 接口
MultiSet 接口与 Bag 接口的功能有些类似:当你向 Set 中存入重复的数据时,它会记录下该数据出现次数,而非重复存储数据本身。
// 伪代码
MultiSet<String> set = new HashMultiSet<>();
set.add("one");
set.add("two");
set.add("two");
set.add("three", 3);
set == [one:1, two:2, three:3]
set.size() == 6
set.getCount("one") == 1
set.getCount("two") == 2
set.getCount("three") == 3
HashMultiSet 比 Bag 『高级』的地方在于,它可以对对象出现的次数作『加减法』:
// 伪代码
set.remove("three");
set.getCount("three") == 2
set.remove("three", 2);
set.getCount("three") == 0
BidiMap 接口
BidiMap 接口继承自 Map 接口,它除了支持 Map 接口的『根据键找值』,还支持反向的『根据值找键』。因为这种行为它被称为 双向 Map 。
BidiMap 接口的实现类有:
-
TreeBidiMap(底层是红黑树)
-
DualHashBidiMap(底层是两个 HashMap)
-
DualLinkedHashBidiMap(底层是两个 LinkedHashMap)
-
DualTreeBidiMap(底层是两个 TreeMap)
map.get(key); // 根据 key 找 value
map.getKey(value); // 根据 value 找 key
删除时也是一样:
map.remove(key); // 以 key 为依据删除键值对
map.removeValue(value); // 以 value 为依据删除键值对
MultiKeyMap 类
MultiKeyMap 实现了由两个 key(甚至更多),来对应一个 value 的数据结构。现实中类似的使用场景有:地理位置和矩阵 。
MultiKeyMap 底层采用 MultiKey 作为普通 Map 的key,采用 HashedMap 存储。
// 伪代码
MultiKeyMap<Integer, String> map = new MultiKeyMap<>();
// 映射键值对关系,方式一
MultiKey<Integer> key = new MultiKey<Integer>(10, 20);
map.put(key, "hello world");
// 映射键值对关系,方式二
map.put(20, 10, "goodbye");
map.get(key) // hello world
map.get(10, 20) // hello world
map.get(20, 10) // goodbye
MultiValuedMap 接口
MultiValuedMap 和 MultiKeyMap 相反,它是支持一个 key 对应多个 值。
它有两个实现类;
-
ArrayListValuedHashMap ,等价于
Map<K, List<V>>
-
HashSetValuedHashMap,等价于
Map<K, Set<V>>
网友评论