apache的commons-collections4

依赖

老版本是 commons-collections,尽量用新版本 commons-collections4 代替

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>

 

CollectionUtils

空集合

//空集合
Collection emptyCollection = CollectionUtils.EMPTY_COLLECTION;
Collection<T> collection = CollectionUtils.emptyCollection();

//如果为null则返回空集合,否则返回原集合(兼容为null的情况)
Collection<T> collection = CollectionUtils.emptyIfNull(collection);

 

检测、判断

boolean isEmpty = CollectionUtils.isEmpty(collection);
boolean isNotEmpty = CollectionUtils.isNotEmpty(collection);

//size是否为空。自身为null或元素数量为0时返回true,obj可以是array、collection、map、iterator
boolean sizeIsEmpty = CollectionUtils.sizeIsEmpty(obj);


//比较2个集合是否相同。引用类型的元素通过equals比较,不要求引用(地址)相同
boolean isEqualCollection = CollectionUtils.isEqualCollection(collection1, collection2);


//是否包含collection2全部的元素
boolean containsAll = CollectionUtils.containsAll(collection1, collection2);

//是否包含其中一些元素,包含其中1个即返回true
boolean containsAny = CollectionUtils.containsAny(collection1, collection2);
boolean containsAny = CollectionUtils.containsAny(collection1, ele...);

 

获取元素、集合信息

//obj可以是array、collection、map、iterator
//实际存储的元素数量
int size = CollectionUtils.size(obj);
//获取指定位置上的元素
Object ele = CollectionUtils.get(obj, index);

//获取指定位置上的键值对
Map.Entry<K, V> entry = CollectionUtils.get(map, index);

 

转换、过滤

//以下都是直接在集合上进行修改

//对集合元素进行转换,返回void
CollectionUtils.transform(list1, transformer);

//过滤元素,返回集合是否变更。filter 只保留满足要求的元素;filterInverse 只保留不满足要求的元素
boolean filter = CollectionUtils.filter(iterable, predicate);
boolean filter = CollectionUtils.filterInverse(iterable, predicate);
//以下都是收集到新集合中,原集合不变

//将满足|不满足条件的元素收集到新集合中。即使没有满足条件的元素,返回的也是空集合,不会返回null
Collection<T> select = CollectionUtils.select(iterable, predicate);
Collection<T> select = CollectionUtils.selectRejected(iterable, predicate);

//将满足|不满足条件的元素收集到指定集合中,返回指定集合(outputCollection)
Collection<T> select = CollectionUtils.select(iterable, predicate, outputCollection);
Collection<T> select = CollectionUtils.selectRejected(iterable, predicate, outputCollection);

//分别将满足条件的元素收集到outputCollection中,不满足的元素收集到rejectedCollection,返回outputCollection
Collection<T> select = CollectionUtils.select(iterable, predicate, outputCollection, rejectedCollection);

 

元素排列

//数组反序排列,直接修改原数组,返回void
CollectionUtils.reverseArray(arr);

//获取元素的所有排列组合情况,一个List<T>对应一种排列组合情况
Collection<List<T>> permutations = CollectionUtils.permutations(collection);

 

增删元素

//添加多个元素,返回的boolean标识集合是否改变
boolean addAll = CollectionUtils.addAll(collection, ele...);
boolean addAll = CollectionUtils.addAll(collection, Iterable|Iterator);

//添加元素,如果元素为null则不添加
boolean addIgnoreNull = CollectionUtils.addIgnoreNull(collection, ele);

 

集合运算
以下都是返回新集合,原集合不变

//遍历iterable1,保留iterable2中包含的所有元素,retain 保留。eg. [1,2,3,3]、[1,3,4] => [1,3,3]
Collection<T> retainAll = CollectionUtils.retainAll(iterable1, iterable2);
//遍历iterable1,移除iterable2中包含的所有元素。eg. [1,2,3,3]、[1,3,4] => [2]
Collection<T> removeAll = CollectionUtils.removeAll(iterable1, iterable2);

//上面的2个方法和下面的几个方法,如果2个集合自身都没有重复元素,那操作结果是相同的,区别在于集合自身中有重复元素时


//求交集,intersection 交叉。eg.[1,2,3,3]、[1,3,3,4] => [1,3,3]
Collection<T> intersection = CollectionUtils.intersection(iterable1, iterable2);


//求并集。eg.[1,2,3,3]、[1,3,4] => [1,2,3,3,4]
Collection<T> union = CollectionUtils.union(iterable1, iterable2);
//求差集。eg.[1,2,3,3]、[1,3,4] => [2,3]
Collection<T> subtract = CollectionUtils.subtract(iterable1, iterable2);
//先用断言对iterable2进行过滤(不会修改list2本身),再求差集
Collection<T> subtract = CollectionUtils.subtract(iterable1, iterable2, predicate);

//获取各自独有的元素组成的集合,即分别求差集,再对差集取并集。eg.[1,2,3,3]、[1,3,4] => [2,3,4]
Collection<T> disjunction = CollectionUtils.disjunction(iterable1, iterable2);



//合并2个有序集合,返回的list元素依然有序
//comparator指定元素的比较方式,缺省时默认为自然排序;includeDuplicates指定是否包含重复的元素
List<T> list = CollectionUtils.collate(iterable1, iterable2, comparator, includeDuplicates);
List<T> list = CollectionUtils.collate(iterable1, iterable2, comparator);
List<T> list = CollectionUtils.collate(iterable1, iterable2, includeDuplicates);
List<T> list = CollectionUtils.collate(iterable1, iterable2);

 

ListUtils

//为null时返回默认list
List<T> list1 = ListUtils.defaultIfNull(list, defaultList);
//为null时返回空集合
List<T> list1 = ListUtils.emptyIfNull(list);


//2个集合是否相等,会比较元素数量、顺序、equals
boolean isEqualList = ListUtils.isEqualList(collection1, collection2);


//同CollectionUtils的同名方法,保留/移除collection2中包含的元素
List<T> retainAll = ListUtils.retainAll(collection1, collection2);
List<T> removeAll = ListUtils.removeAll(collection1, collection2);


//求交集
List<T> intersection = ListUtils.intersection(list1, list2);
//求并集
List<T> union = ListUtils.union(list1, list2);
//求差集
List<T> subtract = ListUtils.subtract(list1, list2);


//查找满足断言的第一个元素,返回index,没有满足的元素返回-1
int index = ListUtils.indexOf(list, predicate);

//将满足/不满足断言的元素收集到list中
List<T> select = ListUtils.select(collection, predicate);
List<T> selectRejected = ListUtils.selectRejected(collection, predicate);


//获取最长公共子序列。eg.[1,2,3,2]、[1,5,2,4] => [1,2]
List<T> list3 = ListUtils.longestCommonSubsequence(list1, list2);
//自定义比较方式
List<T> list3 = ListUtils.longestCommonSubsequence(list1, list2, equator);
String str = ListUtils.longestCommonSubsequence(charSequence1, charSequence2);


//将list切分为多段,size指定每段的元素个数(最后1段元素数量可能不足),一个List<T>对应一段
List<List<T>> partition = ListUtils.partition(list, size);

ListUtils、SetUtils的一些相似方法,比如 isEqualList()、isEqualSet(),入参都是公共父类Collection,但提供的实现分别是针对list、set的,使用时尽量传入对应类型的实参。

 

SetUtils

Set<T> set = SetUtils.emptySet();
SortedSet<T> sortedSet = SetUtils.emptySortedSet();
Set<T> set1 = SetUtils.emptyIfNull(set);

//创建HashSet
HashSet<T> hashSet = SetUtils.hashSet(ele...);


//交集
SetUtils.SetView<T> intersection = SetUtils.intersection(set1, set2);
//并集
SetUtils.SetView<T> union = SetUtils.union(set1, set2);

//求差集,set1-set2
SetUtils.SetView<T> difference = SetUtils.difference(set1, set2);

//获取各自独有的元素组成的集合,即分别求差集,再对差集取并集
SetUtils.SetView<T> disjunction = SetUtils.disjunction(set1, set2);

Set<T> set = disjunction.toSet();


boolean isEqualSet = SetUtils.isEqualSet(collection1, collection2);

 

MapUtils

Map<K, V> map1 = MapUtils.emptyIfNull(map);

boolean isEmpty = MapUtils.isEmpty(map);
boolean isNotEmpty = MapUtils.isNotEmpty(map);

//兼容map为null的情况,map为null时返回0
int size = MapUtils.size(map);


//将键值对中的key、value对换,如果原先多个key对应同一个value,互换后只保留其中最后一个键值对(key),前面的会被覆盖
//在副本上操作,原map不变
Map<K, V> map1 = MapUtils.invertMap(map);


//往map中批量填充键值对,直接修改原map
//第2个参数指定value列表,value直接使用列表中的元素;第3个参数指定key的生成方式,入参value,返回对应的key
MapUtils.populateMap(map, values, value -> key);
//更加灵活,可以自定义key、value的生成方式
MapUtils.populateMap(map, iterable, ele -> key, ele -> value);

 

Bag系列 记录元素出现次数

​interface Bag<E> extends Collection<E>​​ Bag继承自Collection,除了具有Collection的功能,还会记录集合中元素的出现次数,常用实现类有 HashBag、SynchronizedBag、UnmodifiableBag

//使用HashMap存储数据,key存储元素,value存储元素的出现次数
HashBag<T> hashBag = new HashBag<>();
//添加元素指定次数
hashBag.add(ele, count);
//移除元素指定次数
hashBag.remove(ele, count);

//同步的bag,操作使用synchronized加锁
SynchronizedBag synchronizedBag = SynchronizedBag.synchronizedBag(bag);

//不可修改的bag
Bag<Integer> unmodifiableBag = UnmodifiableBag.unmodifiableBag(bag);

 

SetUniqueList 有序、不可重复

结合了 list 有序 可通过下标index操作、set 不可重复的特点

//将List转换为 SetUniqueList,内部使用 ArrayList + HashSet 存储元素
SetUniqueList<String> setUniqueList = SetUniqueList.setUniqueList(list);

 

SingletonMap 有且只能有1个键值对

SingletonMap自始至终有且只能有1个键值对,创建 SingletonMap 实例时就必须初始化键值对,后续不能进行增删操作(会抛出异常)

SingletonMap<K, V> singletonMap = new SingletonMap<>(key, value);
SingletonMap<K, V> singletonMap = new SingletonMap<>(entry);
SingletonMap<K, V> singletonMap = new SingletonMap<>(map);

//缺省参数时默认会初始化一个 null-null 键值对
SingletonMap<K, V> singletonMap = new SingletonMap<>();

 

BidiMap系列 双层映射

Map要求key唯一对应value,不要求value唯一对应key;

BidiMap继承自Map,一个key唯一对应一个value,一个value也唯一对应一个key,常用实现类有 DualHashBidiMap、DualLinkedHashBidiMap、UnmodifiableBidiMap

//内部使用2个HashMap维护映射关系
DualHashBidiMap<K, V> dualHashBidiMap = new DualHashBidiMap<>();

//已存在相同的key时,会覆盖之前对应的value;已存在相同的value时,会覆盖之前对应的key
dualHashBidiMap.put(key, value);

//通过key获取value
V value = dualHashBidiMap.get(key);
//通过value获取key
K key = dualHashBidiMap.getKey(value);


//内部使用2个LinkedHashMap维护映射关系
DualLinkedHashBidiMap<K, V> dualLinkedHashBidiMap = new DualLinkedHashBidiMap<>();

//不可修改的bidiMap
UnmodifiableBidiMap<K, V> unmodifiableBidiMap = new UnmodifiableBidiMap<>(bidiMap);

 

MultiSet 可重复的set

Set 无序、不可重复,MultiSet 无需、可重复,常见的实现类:HashMultiSet、UnmodifiableMultiSet、SynchronizedMultiSet

//内部使用HashMap存储数据,key是元素,value是该元素对应的数量,添加、移除元素只是增减对应元素的数量
HashMultiSet<K> hashMultiSet = new HashMultiSet<>();

//数量默认为1,返回操作是否成功
boolean add = hashMultiSet.add(ele);
boolean remove = hashMultiSet.remove(ele);

//指定添加元素的数量,返回操作之前此元素的数量
int oldCount = hashMultiSet.add(ele, count);
int oldCount = hashMultiSet.remove(ele, count);
//转换为不可修改的MultiSet
MultiSet<T> unmodifiableMultiSet = UnmodifiableMultiSet.unmodifiableMultiSet(multiSet);

//转换为同步的Collection
SynchronizedCollection<T> synchronizedCollection = SynchronizedMultiSet.synchronizedCollection(collection);
//转换为同步的MultiSet
SynchronizedMultiSet<T> synchronizedMultiSet = SynchronizedMultiSet.synchronizedMultiSet(multiSet);

 

MultiKeyMap 多键map

key由多个部分组成,有一定顺序

MultiKeyMap<K, V> multiKeyMap = new MultiKeyMap<>();

//key可以写成多个参数的形式,也可以写成MultiKey,MultiKey使用内置数组来存储key的各个组成部分
multiKeyMap.put(key1, key2, key3..., value);
multiKeyMap.put(new MultiKey<>(key1, key2, key3...), value);


//key... 包括顺序,要完全匹配才算匹配
String value = multiKeyMap.get(key1, key2, key3...);
boolean containsKey = multiKeyMap.containsKey(key1, key2, key3...);


//只要key以key...开头,就会被移除,返回集合是否改变
//eg. multiKeyMap(key1, key2, key3),removeAll(key1, key2) 会被移除,removeAll(key1, key3)、 removeAll(key2, key3) 都不会被移除
boolean modified = multiKeyMap.removeAll(key1, key2);

//key...完全吻合才移除,返回对应的value,不存在时返回null
String value = multiKeyMap.removeMultiKey(key1, key2, key3...);


//map迭代器
MapIterator<MultiKey<? extends K>, V> multiKeyMapIterator = multiKeyMap.mapIterator();

 

MultiValuedMap 多值map

一个key对应多个value。

MultiKeyMap 继承了 Map,MultiValuedMap 则是顶级接口,没有继承Map。MultiValuedMap 常见实现类有

  • ArrayListValuedHashMap:使用 ArrayList 存储key对应的多个value,key => value(ArrayList),同一个key的多个value有序;
  • HashSetValuedHashMap:使用 HashSet 存储key对应的多个value,key => value(HashSet),同一个key的多个value无序、不可重复,put 操作会自动对该key的value去重;
  • UnmodifiableMultiValuedMap:不可变的 MultiValuedMap。
     

ArrayListValuedHashMap、HashSetValuedHashMap 使用方式相同

ArrayListValuedHashMap<K, V> arrayListValuedHashMap = new ArrayListValuedHashMap<>();

arrayListValuedHashMap.put(key, value1);
arrayListValuedHashMap.put(key, value2);

List<V> list = arrayListValuedHashMap.get(key);


//是否包含指定value,只要某个key对应的value列表中含有指定value,就算包含
boolean containsValue = arrayListValuedHashMap.containsValue(value1);

//是否包含指定的映射,只要指定的key存在 && 对应的value列表含有指定value,就算包含
boolean containsMapping = arrayListValuedHashMap.containsMapping(key, value1);

//移除指定的映射关系,返回map是否改变。只移除对应的value,如果移除后该key没有任何关联的value,会移除key
boolean changed = hashSetValuedHashMap.removeMapping(key, value);

//map迭代器
MapIterator<K, V> mapIterator = arrayListValuedHashMap.mapIterator();
//转换为不可变的MultiValuedMap
UnmodifiableMultiValuedMap<K, V> unmodifiableMultiValuedMap = UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(multiValuedMap);

 

MultiMapUtils MultiValuedMap工具类

//空的MultiValuedMap
MultiValuedMap<K, V> emptyMultiValuedMap = MultiMapUtils.EMPTY_MULTI_VALUED_MAP;
MultiValuedMap<K, V> multiValuedMap = MultiMapUtils.emptyMultiValuedMap();

MultiValuedMap<K, V> multiValuedMap1 = MultiMapUtils.emptyIfNull(multiValuedMap);
boolean isEmpty = MultiMapUtils.isEmpty(multiValuedMap);


//new一个ArrayListValuedHashMap
ListValuedMap<K, V> listValuedMap = MultiMapUtils.newListValuedHashMap();
//new一个HashSetValuedHashMap
SetValuedMap<K, V> setValuedMap = MultiMapUtils.newSetValuedHashMap();

//转换为不可变的MultiValuedMa
MultiValuedMap<K, V> unmodifiableMultiValuedMap = MultiMapUtils.unmodifiableMultiValuedMap(multiValuedMap);

 

LRUMap 实现LRU淘汰策略的map

LRU(Least Recently Used)最久未使用,map容量不足时优先移除最久未使用的键值对

//自定义最大容量、初始容量
LRUMap<K, V> lruMap = new LRUMap<>(maxSize, initialSize);
//缺省初始容量时,默认取最大容量
LRUMap<K, V> lruMap = new LRUMap<>(maxSize);
//缺省最大容量时,默认为100
LRUMap<K, V> lruMap = new LRUMap<>();

int maxSize = lruMap.maxSize();

//map是否已经满了(达到maxSize)
boolean isFull = lruMap.isFull();

 

CircularFifoQueue 实现FIFO的环形队列

内部使用数组存储元素,添加元素时,如果队列已经满了,会移除队头的元素,再在队尾添加。
CircularFifoQueue 实现 Queue 接口的同时,也实现了 Collection 接口,具有 Collection 系列的方法

//会创建指定大小的数组
CircularFifoQueue<String> circularFifoQueue = new CircularFifoQueue<>(size);
//size自动取集合的元素个数
CircularFifoQueue<String> circularFifoQueue = new CircularFifoQueue<>(collection);
//缺省参数时size默认取32
CircularFifoQueue<String> circularFifoQueue = new CircularFifoQueue<>();


//队列中存储的元素数量
int size = circularFifoQueue.size();
//指定位置上的元素
T t = circularFifoQueue.get(index);


boolean isEmpty = circularFifoQueue.isEmpty();
//这个方法永远返回false,没有任何意义,因为使用淘汰策略的队列永远不会满,装不下了会根据策略淘汰已有元素,再放入新元素
boolean isFull = circularFifoQueue.isFull();
//内置数组是否已经满了,一般用这个
boolean isAtFullCapacity = circularFifoQueue.isAtFullCapacity();


//添加元素,add是Collection定义的方法,offer是Queue定义的方法,offer()实现中是直接调用add(),实现完全相同
circularFifoQueue.add(ele);
circularFifoQueue.offer(ele);
circularFifoQueue.addAll(collection);


//移除元素,如果该元素在队列中出现多次,只移除第一个出现的。返回是否被移除了,不存在该元素时返回false
circularFifoQueue.remove(ele);
//移除collection包含的所有元素
circularFifoQueue.removeAll(collection);
//清空队列
circularFifoQueue.clear();


//移除并返回队头元素,队列是空的时:poll()返回null,remove()直接抛异常
T t = circularFifoQueue.poll();
T t = circularFifoQueue.remove();


//返回队头元素(不移除),队列是空的时:peek()返回null,element()直接抛异常
T t = circularFifoQueue.peek();
T t = circularFifoQueue.element();

 

spring-core util包

CollectionUtils

检测、判断

//collectio|map是否为空
boolean isEmpty = CollectionUtils.isEmpty(collection|map);

//collection是否只有1个元素
boolean hasUniqueObject = CollectionUtils.hasUniqueObject(collection);


//迭代器中是否包含指定元素
boolean contains = CollectionUtils.contains(Iterator<?> iterator, ele);

//是否包含指定实例。注意:此方法是使用 == 判断,并非使用equals
boolean containsInstance = CollectionUtils.containsInstance(collection, ele);

//collection1是否包含collection2的一些元素,只要包含其中1个元素就返回true
boolean b = CollectionUtils.containsAny(collection1, collection2);

 

查找、获取

//返回list|set中的第1个|最后1个元素
T t = CollectionUtils.firstElement(collection);
T t = CollectionUtils.lastElement(collection);


//返回collection2中第一个被包含在collection1中的元素
Integer firstMatch = CollectionUtils.findFirstMatch(collection1, collection2);

//获取元素类型
Class<?> clazz = CollectionUtils.findCommonElementType(collection);


//查找指定类型的元素,集合中该类型有且仅有1个元素时 返回集合中的对应元素,否则返回null
T t = CollectionUtils.findValueOfType(collection, clazz);
//查找指定类型的元素。遍历Class[],集合中该类型有且仅有1个元素时 返回集合中的对应元素,如果遍历完Class[]都没有,则返回null
T t = CollectionUtils.findValueOfType(collection, Class[]);

 

合并、转换

//合并数组元素到collection中
CollectionUtils.mergeArrayIntoCollection(Object array, collection);
//合并properties的键值对到map中
CollectionUtils.mergePropertiesIntoMap(Properties properties, map);


//数组转list。底层调用的还是Arrays.asList(),但在Arrays.asList()的基础上兼容了入参为null的情况
List list = CollectionUtils.arrayToList(Object arr);


//将map转换为MultiValueMap
MultiValueMap<K, V> multiValueMap = CollectionUtils.toMultiValueMap(map);
//转换为不可修改的MultiValueMap
MultiValueMap<K, V> unmodifiableMultiValueMap = CollectionUtils.unmodifiableMultiValueMap(multiValueMap);

 

MultiValueMap 多值map

常用实现类 LinkedMultiValueMap,内部使用 LinkedHashMap 实现 ​​Map<K, List<V>> targetMap = new LinkedHashMap<>();​

//缺省初始容量时,默认16
LinkedMultiValueMap<K, V> multiValueMap = new LinkedMultiValueMap<>(initialCapacity);
LinkedMultiValueMap<K, V> multiValueMap = new LinkedMultiValueMap<>();


//把value添加到对应的value列表中
multiValueMap.add(key, value1);
multiValueMap.add(key, value2);
multiValueMap.addAll(key, valueList);

//直接覆盖对应的value列表
multiValueMap.put(key, valueList);
//直接覆盖对应的value列表,value会作为value列表的唯一元素
multiValueMap.set(key, value);


//一个List<V>对应一个key的value列表
Collection<List<V>> allValue = multiValueMap.values();
//key的数量
int size = multiValueMap.size();

boolean empty = multiValueMap.isEmpty();
boolean containsKey = multiValueMap.containsKey(key);
//value要等价于该key的value列表,才会返回true
boolean containsValue = multiValueMap.containsValue(value);


List<V> values = multiValueMap.get(key);
//获取该key的value列表中的第一个value
V first = multiValueMap.getFirst(key);


//移除指定键值对,返回对应的values
List<V> remove = multiValueMap.remove(key);
multiValueMap.clear();