
com.aggrepoint.utils.CollectionUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aputils Show documentation
Show all versions of aputils Show documentation
Common utilities used by both Dao and Winlet project
The newest version!
package com.aggrepoint.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
*
* @author jiangmingyang
*/
public class CollectionUtils {
public static T first(Collection entities,
Function compare) {
if (entities == null)
return null;
for (T t : entities)
if (compare.apply(t))
return t;
return null;
}
public static boolean firstThen(Collection entities,
Function compare, Consumer then) {
if (entities == null)
return false;
T t = first(entities, compare);
if (t == null)
return false;
then.accept(t);
return true;
}
public static List toList(Collection entities,
Function mapper) {
if (entities == null)
return null;
return entities.stream().map(mapper).filter(p -> p != null)
.collect(Collectors.toList());
}
public static List toList(Collection entities,
Predicate predicate, Function mapper) {
if (entities == null)
return null;
return entities.stream().filter(predicate).map(mapper)
.filter(p -> p != null).collect(Collectors.toList());
}
public static Set toSet(Collection entities,
Function mapper) {
if (entities == null)
return null;
return entities.stream().map(mapper).filter(p -> p != null)
.collect(Collectors.toSet());
}
public static > M toMap(Collection entities,
Function keyMapper, Supplier supplier) {
if (entities == null)
return null;
return entities.stream().collect(
Collectors.toMap(keyMapper, Function.identity(), (a, b) -> b,
supplier));
}
public static > M toMap(
Collection entities, Function keyMapper,
Function valueMapper, Supplier supplier) {
if (entities == null)
return null;
return entities.stream()
.collect(
Collectors.toMap(keyMapper, valueMapper, (a, b) -> b,
supplier));
}
/**
* Convert a collection to HashMap, The key is decided by keyMapper, value
* is the object in collection
*
* @param entities
* @param keyMapper
* @return
*/
public static HashMap toHashMap(Collection entities,
Function keyMapper) {
return toMap(entities, keyMapper, HashMap::new);
}
public static HashMap toHashMap(T[] entities,
Function keyMapper) {
return toHashMap(Arrays.asList(entities), keyMapper);
}
public static HashMap toHashMap(Collection entities,
Function keyMapper, Function valueMapper) {
return toMap(entities, keyMapper, valueMapper, HashMap::new);
}
public static HashMap toHashMap(T[] entities,
Function keyMapper, Function valueMapper) {
return toHashMap(Arrays.asList(entities), keyMapper, valueMapper);
}
/**
* Convert a collection to Hashtable. The key is decided by keyMapper, value
* is the object in collection
*
* @param entities
* @param keyMapper
* @return
*/
public static Hashtable toHashtable(Collection entities,
Function keyMapper) {
return toMap(entities, keyMapper, Hashtable::new);
}
public static Hashtable toHashtable(T[] entities,
Function keyMapper) {
return toHashtable(Arrays.asList(entities), keyMapper);
}
public static Hashtable toHashtable(Collection entities,
Function keyMapper, Function valueMapper) {
return toMap(entities, keyMapper, valueMapper, Hashtable::new);
}
public static Hashtable toHashtable(T[] entities,
Function keyMapper, Function valueMapper) {
return toHashtable(Arrays.asList(entities), keyMapper, valueMapper);
}
public static > HashMap group(
Collection entities, Function keyMapper,
Function valueMapper, Supplier collectionFactory) {
if (entities == null)
return null;
return entities.stream().collect(
Collectors.groupingBy(
keyMapper,
HashMap::new,
Collectors.mapping(valueMapper,
Collectors.toCollection(collectionFactory))));
}
public static HashMap> group(
Collection entities, Function keyMapper,
Function valueMapper) {
return group(entities, keyMapper, valueMapper, HashSet::new);
}
public static HashMap> groupAsList(
Collection entities, Function keyMapper) {
return group(entities, keyMapper, Function.identity(), ArrayList::new);
}
public static HashMap> groupAsList(
Collection entities, Function keyMapper,
Function valueMapper) {
return group(entities, keyMapper, valueMapper, ArrayList::new);
}
public static HashMap groupJoining(
Collection entities, Function keyMapper,
Function valueMapper, String delimiter) {
if (entities == null)
return null;
return entities.stream().collect(
Collectors.groupingBy(
keyMapper,
HashMap::new,
Collectors.mapping(valueMapper,
Collectors.joining(delimiter))));
}
public static HashMap> group(T[] entities,
Function keyMapper, Function valueMapper) {
return group(Arrays.asList(entities), keyMapper, valueMapper);
}
/**
* Grouping into 2 levels
*
* @param entities
* @param keyMapper1
* @param keyMapper2
* @param valueMapper
* @param collectionFactory
* @return
*/
public static > HashMap> groupTwice(
Collection entities, Function keyMapper1,
Function keyMapper2, Function valueMapper,
Supplier collectionFactory) {
if (entities == null)
return null;
return entities.stream().collect(
Collectors.groupingBy(keyMapper1, HashMap::new, Collectors
.groupingBy(keyMapper2, HashMap::new, Collectors
.mapping(valueMapper, Collectors
.toCollection(collectionFactory)))));
}
/**
* Similar to grouping into 2 levels except each unit is not a Collection
* but a single object
*
* @param entities
* @param keyMapper1
* @param keyMapper2
* @param valueMapper
* @return
*/
public static HashMap> matrix(
Collection entities, Function keyMapper1,
Function keyMapper2, Function valueMapper) {
if (entities == null)
return null;
return entities.stream().collect(
Collectors.groupingBy(keyMapper1, HashMap::new, Collectors
.toMap(keyMapper2, valueMapper, (a, b) -> a,
HashMap::new)));
}
/**
* Extract attribute from objects in collection and store them in array and
* return.
*
* @param entities
* @param keyMapper
* @param arr
* @return
*/
public static K[] toArray(Collection entities,
Function keyMapper, K[] arr) {
if (entities == null)
return null;
return entities.stream().map(keyMapper).toArray(size -> arr);
}
/**
* Move an object in List up
*
* @param list
* @param key
* @param keyMapper
* @return
*/
public static boolean moveUp(List list, K key,
Function keyMapper, int n) {
if (list == null)
return false;
ArrayList newList = new ArrayList();
boolean changed = false;
for (int i = 0; i < list.size(); i++) {
T item = list.get(i);
if (i > 0 && key.equals(keyMapper.apply(item))) {
int posi = i - n;
if (posi < 0)
posi = 0;
newList.add(posi, item);
changed = true;
} else
newList.add(item);
}
if (changed) {
list.clear();
list.addAll(newList);
return true;
}
return false;
}
public static boolean moveUp(List list, K key,
Function keyMapper) {
return moveUp(list, key, keyMapper, 1);
}
/**
* Move an object in List down
*
* @param list
* @param key
* @param keyMapper
* @return
*/
public static boolean moveDown(List list, K key,
Function keyMapper, int n) {
if (list == null)
return false;
ArrayList newList = new ArrayList();
boolean changed = false;
int start = list.size() - 1;
for (int i = start; i >= 0; i--) {
T item = list.get(i);
if (i != start && key.equals(keyMapper.apply(item))) {
int posi = n;
if (newList.size() < posi)
posi = newList.size();
newList.add(posi, item);
changed = true;
} else
newList.add(0, item);
}
if (changed) {
list.clear();
list.addAll(newList);
return true;
}
return false;
}
public static boolean moveDown(List list, K key,
Function keyMapper) {
return moveDown(list, key, keyMapper, 1);
}
/**
* 将列表中id为key的项向前或向后移动n个位置。n为正表示向后移动,n为负表示向前移动。
*
* @param list
* @param key
* @param keyMapper
* @param n
* @return
*/
public static boolean move(List list, K key,
Function keyMapper, int n) {
if (n == 0)
return false;
if (n > 0)
return moveDown(list, key, keyMapper, n);
return moveUp(list, key, keyMapper, -n);
}
/**
* 如果before为true则把key移动到ref前面,否则把key移动到ref后面
*
* @param list
* @param key
* @param ref
* @param keyMapper
* @param before
* @return 被移动的元素移动后在列表中的位置,-1表示没有被移动
*/
public static List move(List list, K key, K ref,
Function keyMapper, boolean before,
Function orderGet, OrderSetter orderSet, int orderGap) {
if (key == ref)
return null;
// { 找到要移动的项和参考项所在位置
int keyidx = -1;
int refidx = -1;
int idx = 0;
for (T t : list) {
K id = keyMapper.apply(t);
if (id.equals(key))
keyidx = idx;
if (id.equals(ref))
refidx = idx;
if (keyidx != -1 && refidx != -1)
break;
idx++;
}
if (keyidx == -1 || refidx == -1)
return null;
// }
// { 拿走要移动的项
T t = list.remove(keyidx);
if (refidx >= keyidx)
refidx--;
if (!before)
refidx++;
// }
// 放回要移动的项
list.add(refidx, t);
// { 设置排序位置
ArrayList moved = new ArrayList();
int startOrder = 0;
if (refidx > 0)
startOrder = orderGet.apply(list.get(refidx - 1));
for (int i = refidx + 1; i < list.size(); i++) {
int order = orderGet.apply(list.get(i));
if (order - startOrder >= i - refidx + 1) {
int gap = (order - startOrder) / (i - refidx + 1);
for (int j = refidx; j < i; j++) {
T move = list.get(j);
orderSet.apply(move, startOrder + (j - refidx + 1) * gap);
moved.add(move);
}
return moved;
}
}
for (int i = refidx; i < list.size(); i++) {
T move = list.get(i);
orderSet.apply(move, startOrder + (i - refidx + 1) * orderGap);
moved.add(move);
}
return moved;
// }
}
/**
* 建立树形结构
*
* @param list
* @param keyMapper
* @param parentKeyMapper
* @param childMapper
* @return
*/
public static ArrayList buildTree(Collection list,
Function keyMapper, Function parentKeyMapper,
Function> childMapper) {
HashMap map = toHashMap(list, keyMapper);
ArrayList root = new ArrayList();
for (T t : list) {
K key = keyMapper.apply(t);
K parentKey = parentKeyMapper.apply(t);
if (parentKey == null || key.equals(parentKey))
root.add(t);
else
childMapper.apply(map.get(parentKey)).add(t);
}
return root;
}
public static ArrayList copyTrees(Collection trees,
Function keyMapper, Function> childMapper,
Function cloneMapper, Collection toCopy) {
ArrayList copy = new ArrayList();
if (toCopy == null)
return copy;
for (T node : trees) {
T copyNode = copyTree(node, keyMapper, childMapper, cloneMapper,
toCopy);
if (copyNode != null)
copy.add(copyNode);
}
return copy;
}
public static T copyTree(T node, Function keyMapper,
Function> childMapper, Function cloneMapper,
Collection toCopy) {
if (toCopy == null)
return null;
T copy = null;
Collection children = childMapper.apply(node);
if (children != null && children.size() > 0) {
for (T child : children) {
T childCopy = copyTree(child, keyMapper, childMapper,
cloneMapper, toCopy);
if (childCopy != null) {
if (copy == null)
copy = cloneMapper.apply(node);
childMapper.apply(copy).add(childCopy);
}
}
}
if (copy == null && toCopy.contains(keyMapper.apply(node)))
copy = cloneMapper.apply(node);
return copy;
}
public static int[] toArray(Collection col) {
if (col == null)
return null;
int[] arr = new int[col.size()];
int i = 0;
for (Integer v : col)
arr[i++] = v.intValue();
return arr;
}
public static Collection sort(Collection list,
Function order, boolean asc) {
if (list == null || order == null)
return list;
ArrayList ar = new ArrayList();
ar.addAll(list);
ar.sort((p1, p2) -> {
Number order1 = order.apply(p1);
Number order2 = order.apply(p2);
if (order1.doubleValue() > order2.doubleValue())
return asc ? 1 : -1;
else if (order1.doubleValue() < order2.doubleValue())
return asc ? -1 : 1;
return 0;
});
list.clear();
list.addAll(ar);
return list;
}
public static Collection sort(Collection list,
Function order) {
return sort(list, order, true);
}
/**
* 用于为Collection中的父对象加载子对象。子对象加载应以父对象的key的集合为条件,父对象中应该有一个集合用于存放子对象。
*
* 例如父对象Parent有属性id和集合childs,子对象Child有属性parentId。假设
* loader.load()可以根据parentId加载子对象集合,对于类型为List的parents:
*
*
* loadChild(parents, Parent::getId, Parent::getChilds, ids -> loader.load(ids),
* Child::getParentId);
*
*/
public static void loadChildren(Collection list,
Function keyMapper,
Function> childCollectionMapper,
Function, Collection> loader,
Function childKeyMapper) {
if (list == null || list.size() == 0)
return;
HashMap map = toHashMap(list, keyMapper);
loader.apply(map.keySet()).forEach(
p -> childCollectionMapper.apply(
map.get(childKeyMapper.apply(p))).add(p));
}
/**
* list为装有类型为T的对象的集合,称为集合一。用T对象中通过keyGetter获得的key值组成集合,调用
* loader,可以获得类型为S的对象集合,称为集合二。T和S的关系是N对1。把集合一中通过
* keyGetter获得的关键值与集合二中通过loadedKeyGetter获得关键值相同的T和S对象匹配,调用match。
*/
public static > X loadNToOne(X list,
Function keyGetter,
Function, Collection> loader,
Function loadedKeyGetter, BiConsumer match) {
if (list == null || list.size() == 0)
return list;
Set keys = toSet(list, keyGetter);
if (keys == null || keys.size() == 0)
return list;
Collection subs = loader.apply(keys);
if (subs == null || subs.size() == 0)
return list;
HashMap map = toHashMap(subs, loadedKeyGetter);
for (T item : list) {
K key = keyGetter.apply(item);
if (key == null)
continue;
S sub = map.get(key);
if (sub == null)
continue;
match.accept(item, sub);
}
return list;
}
/**
* list为装有类型为T的对象的集合,称为集合一。用T对象中通过keyGetter获得的key值组成集合,调用
* loader,可以获得类型为S的对象集合,称为集合二。T和S的关系是1对N。把集合一中通过
* keyGetter获得的关键值与集合二中通过loadedKeyGetter获得关键值相同的T和S对象匹配,调用match。
*/
public static > X loadOneToN(X list,
Function keyGetter,
Function, Collection> loader,
Function loadedKeyGetter, BiConsumer match) {
if (list == null || list.size() == 0)
return list;
Set keys = toSet(list, keyGetter);
if (keys == null || keys.size() == 0)
return list;
Collection subs = loader.apply(keys);
if (subs == null || subs.size() == 0)
return list;
HashMap map = toHashMap(list, keyGetter);
for (S sub : subs) {
T item = map.get(loadedKeyGetter.apply(sub));
if (item == null)
continue;
match.accept(item, sub);
}
return list;
}
public static List asList(T obj) {
if (obj == null)
return null;
List list = new ArrayList();
list.add(obj);
return list;
}
/**
* 把obj包装为集合,调用function
*/
public static T callAsCollection(T obj, Consumer> function) {
if (obj == null)
return null;
List list = new ArrayList();
list.add(obj);
function.accept(list);
return obj;
}
public static T findOrFirst(Collection list, Function mapper,
T toFind) {
if (list == null || list.size() == 0)
return null;
if (toFind != null)
for (K k : list)
if (mapper.apply(k).equals(toFind))
return toFind;
return mapper.apply(list.iterator().next());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy