前言
再日常的业务开发中,常少不了list for循环处理。 在查询mysql业务中,通常不会在for循环中去查询,而是一次去查询符合条件的数据,以避免频繁的释放和获取连接,然后转成map或者分组,在for 循环中通过注解去get处理。
在菜单和多级分类或者文件夹父子结构的数据中。又少不了一些过滤筛选。等等。所以封装出工具类。以便日常开发使用。
代码。
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DataUtil {
public static <T, K> List<T> list2Tree(
Collection<T> list,
Function<T, K> getPidFunction,
Function<T, K> getIdFunction,
BiConsumer<T, List<T>> setSon,
K heard) {
List<T> ts = new ArrayList<>();
for (T t : list) {
boolean flag;
K pid = getPidFunction.apply(t);
if (heard == null) {
flag = pid == null;
} else {
flag = pid != null && pid.equals(heard);
}
if (flag) {
findSon(list, t, getIdFunction, getPidFunction, setSon);
ts.add(t);
}
}
return ts;
}
public static <T> void listForeach(List<T> ts, Consumer<T> consumer) {
ts.forEach(consumer);
}
public static <T> boolean treeNodeFilter(
T t, Predicate<T> predicate, Function<T, List<T>> getSon, BiConsumer<T, List<T>> setSon) {
if (predicate.test(t)) {
log.info("检测通过");
return true;
} else {
List<T> sonTrees = getSon.apply(t);
log.info("检测不通过 检测子节点");
if (!isEmpty(sonTrees)) {
List<T> tmpSonTree = new ArrayList<>();
boolean flag = false;
for (T son : sonTrees) {
if (treeNodeFilter(son, predicate, getSon, setSon)) {
flag = true;
tmpSonTree.add(son);
}
}
log.info("子节点检测结果:{}", flag);
setSon.accept(t, tmpSonTree);
return flag;
} else {
log.info("没有子节点");
return false;
}
}
}
public static <T, K> void findSon(
Collection<T> list,
T t,
Function<T, K> getIdFunction,
Function<T, K> getParentFunction,
BiConsumer<T, List<T>> setSon) {
K k = getIdFunction.apply(t);
List<T> sonList =
listTypeFilter(
list, p -> getParentFunction.apply(p) != null && getParentFunction.apply(p).equals(k));
sonList.forEach(p -> findSon(list, p, getIdFunction, getParentFunction, setSon));
setSon.accept(t, sonList);
}
public static <T, K> List<T> getChildList(
Collection<T> list, Function<T, K> getPidFunction, Function<T, K> getIdFunction, K id) {
List<T> result = new ArrayList<>();
for (T t : list) {
if (getPidFunction.apply(t).equals(id)) {
result.addAll(getChildList(list, getPidFunction, getIdFunction, getIdFunction.apply(t)));
result.add(t);
}
}
return result;
}
public static <T, K> List<K> listTypeChange(Collection<T> ts, Function<T, K> function) {
if (ts != null && ts.size() > 0) {
return ts.parallelStream().map(function).collect(Collectors.toList());
} else {
return new ArrayList<>();
}
}
public static <T, K> List<K> listTypeChange(
Collection<T> ts, Predicate<T> biPredicate, Function<T, K> function) {
if (ts != null && ts.size() > 0) {
return ts.parallelStream().filter(biPredicate).map(function).collect(Collectors.toList());
} else {
return new ArrayList<>();
}
}
public static boolean isEmpty(Collection list) {
return list == null || list.size() == 0;
}
public static <T, K> Set<K> listTypeChangeAnd2Set(Collection<T> ts, Function<T, K> function) {
if (ts != null && ts.size() > 0) {
return ts.parallelStream().map(function).collect(Collectors.toSet());
} else {
return new HashSet<>();
}
}
public static <T> List<T> listTypeFilter(Collection<T> ts, Predicate<T> biPredicate) {
if (ts != null && ts.size() > 0) {
return ts.parallelStream().filter(biPredicate).collect(Collectors.toList());
} else {
return new ArrayList<>();
}
}
public static <T, K> Map<K, T> listToMap(Collection<T> ts, Function<T, K> function) {
return ts.parallelStream().collect(Collectors.toMap(function, t -> t));
}
public static <T, K> Map<K, List<T>> listGroup(Collection<T> ts, Function<T, K> function) {
return ts.parallelStream().collect(Collectors.groupingBy(function));
}
public static <T, K> Map<K, Long> listGroupCount(List<T> ts, Function<T, K> function) {
return ts.parallelStream().collect(Collectors.groupingBy(function, Collectors.counting()));
}
public static <T, U extends Comparable<? super U>> List<T> distinct(
Collection<T> ts, Function<? super T, ? extends U> keyExtractor) {
return ts.stream()
.collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<T>(Comparator.comparing(keyExtractor))),
ArrayList::new));
}
public static boolean emptyCollection(Collection collection) {
return collection == null || collection.size() == 0;
}
public static <T> List<List<T>> getAllPath(
T t,
List<List<T>> lists,
List<T> nodes,
Function<T, List<T>> getSonFunc,
BiConsumer<T, List<T>> setSon) {
List<T> childNodes = new ArrayList<>();
if (getSonFunc.apply(t) != null) {
childNodes = Lists.newCopyOnWriteArrayList(getSonFunc.apply(t));
}
setSon.accept(t, null);
nodes.add(t);
if (DataUtil.isEmpty(childNodes)) {
lists.add(nodes);
} else {
for (T son : childNodes) {
List<T> copyNodes = Lists.newCopyOnWriteArrayList(nodes);
getAllPath(son, lists, copyNodes, getSonFunc, setSon);
}
}
return lists;
}
public static <T> List<T> tree2List(
T t, Function<T, List<T>> getSonFunc, BiConsumer<T, List<T>> setSon) {
List<T> list = new ArrayList<>();
List<T> sons = new ArrayList<>();
if (getSonFunc.apply(t) != null) {
sons = Lists.newCopyOnWriteArrayList(getSonFunc.apply(t));
}
setSon.accept(t, null);
list.add(t);
if (!isEmpty(sons)) {
for (T son : sons) {
list.addAll(tree2List(son, getSonFunc, setSon));
}
}
return list;
}
public static <T> List<T> treeListFilter(
List<T> trees,
Predicate<T> pi,
Function<T, List<T>> getSonFunc,
BiConsumer<T, List<T>> setSon) {
trees =
listTypeFilter(
trees,
ts ->
treeNodeFilter(
ts,
pi,
getSonFunc,
setSon));
return trees;
}
}