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();