一个通用的lambda stream流处理工具, 包含了工作中绝大部分场景常用的使用方式
import java.math.BigDecimal;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;/*** lambda strem流表达式处理工具** @Date 2021/6/3 10:59 下午*/
public class LambdaUtils {/*** 默认分隔符*/public static final String DEFAULT_SPLIT_CHAR = ",";/*** 默认连接符*/public static final String DEFAULT_CONNECTOR_CHAR = "&&";/*** 查找list中的第一个** @param datas list数据* @param <T> list中的理性* @return 找到的第一个,可能为空*/public static <T> T findFirstOrNull(List<T> datas) {return findFirstOrDefault(datas, null);}public static <T> T findFirstOrDefault(List<T> datas, T t) {return Optional.ofNullable(datas).flatMap(e -> e.stream().findFirst()).orElse(t);}/*** 返回null或者默认值*/public static <T> T getOrDefault(T t, T def) {return Optional.ofNullable(t).orElse(def);}/*** 展平嵌套列表的工具方法,将嵌套list转换为单层list** @param listOfLists 嵌套的list* @param <T> list中的类型* @return 展平之后的list*/public static <T> List<T> flattenList(List<List<T>> listOfLists) {return listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());}/*** 基于某个键值进行去重的工具方法, 使用map去重, 丢失了原来的顺序** @param list 参数list* @param keyExtractor 获取键值的函数* @param <T> list中数据的类型* @param <R> 去重字段的类型* @return 去重之后的list*/public static <T, R> List<T> distinctByKey(List<T> list, Function<? super T, R> keyExtractor) {if (CollectionUtils.isEmpty(list)) {return new ArrayList<>(0);}return new ArrayList<>(list.stream().collect(Collectors.toMap(keyExtractor, Function.identity(), (oo, no) -> oo)).values());}/*** 保持原有的顺序,去重*/public static <T, R> List<T> distinctByKeySort(List<T> list, Function<? super T, R> keyExtractor) {if (list == null) {return new ArrayList<>(0);}Set<R> seen = new LinkedHashSet<>(list.size());return list.stream().filter(element -> seen.add(keyExtractor.apply(element))).collect(Collectors.toList());}/*** 根据给定的判断将列表分区为两个子列表的工具方法, 满足判断条件的根据true获取结果, 不满足判断条件的根据false获取结果** @param list 需要被分区的list* @param predicate 分区的条件* @param <T> list中数据的类型* @return 分区后的map*/public static <T> Map<Boolean, List<T>> partitionBy(List<T> list, Predicate<T> predicate) {return Optional.ofNullable(list).map(items -> items.stream().collect(Collectors.partitioningBy(predicate))).orElse(new HashMap<>(0));}/*** 根据某个条件删除集合中的元素, 条件为true则删除** @param collection 集合对象* @param predicate 删除条件* @param <T> 集合中的数据类型*/public static <T> void removeIf(Collection<T> collection, Predicate<T> predicate) {if (collection != null) {collection.removeIf(predicate);}}public static <T> void dealAndConsumer(List<T> datas, Consumer<T> consumer) {Optional.ofNullable(datas).ifPresent(list -> list.forEach(consumer));}/*** 用func处理list中的每一条数据, 并收集到list中返回** @param datas list数据* @param func 处理每条数据的函数* @param <T> datas的数据类型* @param <R> func处理后的数据类型*/public static <T, R> List<R> dealAndtoList(List<T> datas, Function<T, R> func) {return Optional.ofNullable(datas).map(list -> list.stream().map(func).collect(Collectors.toList())).orElse(new ArrayList<>(0));}public static <T, R> List<R> dealAndtoFlattenList(List<T> datas, Function<T, List<R>> func) {return Optional.ofNullable(datas).map(list -> list.stream().map(func).flatMap(List::stream).collect(Collectors.toList())).orElse(new ArrayList<>(0));}/*** 处理嵌套list, func函数用来处理外部list获得嵌套的list, nestedFunc函数用来生成嵌套list的返回结果** @param datas 原始数据列表,可以是任何类型* @param func 函数,用于将列表中的每个元素转换为另一个列表* @param nestedFunc 嵌套函数,用于进一步处理转换后的列表中的每个元素* @return 处理后的列表,包含通过嵌套函数处理过的元素*/public static <OT, NT, NR> List<NR> dealAndNestedFlattenList(List<OT> datas, Function<OT, List<NT>> func, Function<NT, NR> nestedFunc) {// 使用Optional处理可能的null输入,确保在输入为null时返回空列表而不是抛出异常return Optional.ofNullable(datas)// 将列表中的每个元素使用提供的函数进行转换,然后通过flatMap进行扁平化处理.map(list -> list.stream().map(func).flatMap(List::stream)// 对扁平化后的每个元素应用嵌套函数,并收集到一个新的列表中.map(nestedFunc).collect(Collectors.toList()))// 如果输入为null,返回空列表.orElse(new ArrayList<>(0));}/*** 处理嵌套list, func函数用来处理外部list获得嵌套的list, outReturnFunc函数用来生成外部list返回的结果, nestedFunc函数用来生成嵌套list的返回结果* @param datas 数据源* @param func 获得嵌套list的函数* @param outReturnFunc 获得外部list结果的函数* @param nestedFunc 获得内部list结果的函数* @return 一个pair对象, 第一个元素是外部list的结果, 第二个元素是内部list的结果* @param <OT> 外层list的元素类型* @param <NT> 内部list的元素类型* @param <OR> 外部list的返回结果* @param <NR> 内部list的返回结果*/public static <OT, NT, OR, NR> Pair<List<OR>, List<NR>> dealAndNestedFlattenList(List<OT> datas, Function<OT, List<NT>> func, Function<OT, OR> outReturnFunc, Function<NT, NR> nestedFunc) {if (CollectionUtils.isEmpty(datas)) {return Pair.of(new ArrayList<>(0), new ArrayList<>(0));}List<OR> outResult = new ArrayList<>(datas.size());List<NR> innserResult = new ArrayList<>();for (OT data : datas) {// 外部list返回的结果OR outRt = outReturnFunc.apply(data);outResult.add(outRt);// 内部listList<NT> innerList = func.apply(data);if (CollectionUtils.isEmpty(innerList)) {continue;}for (NT r : innerList) {// 内部list返回的结果NR innerRt = nestedFunc.apply(r);innserResult.add(innerRt);}}return Pair.of(outResult, innserResult);}/*** 将datas中的数据按照func处理,返回处理后的数据集合,然后将该集合给consumer消费** @param datas list数据* @param func 处理每条数据的函数* @param consumer 消费func处理后的数据集* @param <T> datas的数据类型* @param <R> func处理后的数据类型*/public static <T, R> void dealAndConsumer(List<T> datas, Function<T, R> func, Consumer<List<R>> consumer) {Optional.ofNullable(datas).map(list -> list.stream().map(func).collect(Collectors.toList())).ifPresent(consumer);}/*** 用func处理list中的每条数据,然后给consumer消费;如果func处理的某条数据为空,那么该条数据不会被consumer消费*/public static <T, R> void dealAndConsumerWithoutNull(List<T> datas, Function<T, R> func,Consumer<List<R>> consumer) {Optional.ofNullable(datas).map(list -> list.stream().map(func).filter(Objects::nonNull).collect(Collectors.toList())).ifPresent(consumer);}/*** 用func处理set中的每条数据,然后给consumer消费;如果处理的为空,那么不会被consumer消费*/public static <T, R> void dealAndConsumerWithoutNull(Set<T> datas, Function<T, R> func, Consumer<Set<R>> consumer) {Optional.ofNullable(datas).map(set -> set.stream().map(func).filter(Objects::nonNull).collect(Collectors.toSet())).ifPresent(consumer);}/*** list转map,转换后的key不会重复(如果有key冲突, 前者覆盖后者)** @param datas 待转换的list* @param keyFunc 生成key的函数,例如 Class::getName* @param <T> list集合中的元素类型* @param <R> 生成的map的key的类型* @return 返回生成的map对象*/public static <T, R> Map<R, T> list2Map(List<T> datas, Function<T, R> keyFunc) {return Optional.ofNullable(datas).map(as -> as.stream().collect(Collectors.toMap(keyFunc, Function.identity(), (eo, no) -> eo))).orElse(new HashMap<>(0));}/*** list转map,转换后的key不会重复(如果有key冲突, 前者覆盖后者); 注意: 如果valFunc得到的结果是null,将会NPE异常** @param datas 待转换的list* @param keyFunc 生成key的函数,例如 Class::getName* @param valFunc 生成value的函数,例如 Class::getName* @param <T> list集合中的元素类型* @param <R> 生成的map的key的类型* @param <V> 生成的map的value的类型* @return 返回生成的map对象*/public static <T, R, V> Map<R, V> list2Map(List<T> datas, Function<T, R> keyFunc, Function<T, V> valFunc) {return Optional.ofNullable(datas).map(as -> as.stream().collect(Collectors.toMap(keyFunc, valFunc, (eo, no) -> no))).orElse(new HashMap<>(0));}/*** 根据两个个key值生成map*/public static <T> Map<String, T> list2MapMultiKey(List<T> datas, Function<T, Object> keyFunc, Function<T, Object> keyFunc2) {return Optional.ofNullable(datas).map(as -> as.stream().collect(Collectors.toMap(e -> keyFunc.apply(e) + DEFAULT_CONNECTOR_CHAR + keyFunc2.apply(e), Function.identity(), (eo, no) -> no))).orElse(new HashMap<>(0));}/*** 过滤掉list中的null元素** @param datas 待过滤的list* @param <T> list中的元素类型* @return 去掉null元素的之后的list结合*/public static <T> List<T> filterNull(List<T> datas) {return Optional.ofNullable(datas).map(list -> list.stream().filter(Objects::nonNull).collect(Collectors.toList())).orElse(new ArrayList<>(0));}/*** 过滤list中的元素** @param datas 待过滤的list* @param predicate 过滤条件* @param <T> list中的元素类型* @return 过滤后的list*/public static <T> List<T> filter(List<T> datas, Predicate<T> predicate) {return Optional.ofNullable(datas).map(list -> list.stream().filter(predicate).collect(Collectors.toList())).orElse(new ArrayList<>(0));}public static <T> boolean anyMatch(List<T> datas, Predicate<T> predicate) {return Optional.ofNullable(datas).map(list -> list.stream().anyMatch(predicate)).orElse(false);}public static <T> boolean allMatch(List<T> datas, Predicate<T> predicate) {return Optional.ofNullable(datas).map(list -> list.stream().allMatch(predicate)).orElse(false);}public static <T> boolean noneMatch(List<T> datas, Predicate<T> predicate) {return Optional.ofNullable(datas).map(list -> list.stream().noneMatch(predicate)).orElse(false);}/*** list转string,以,分割** @param datas list数据* @param func 处理list中每个元素的函数* @param <T> list中的数据类型* @return 处理后的string, 如果datas为空,默认返回null*/public static <T> String list2Str(List<T> datas, Function<T, String> func) {return list2StrWithSeparator(datas, func, DEFAULT_SPLIT_CHAR);}/*** list转string,自定义分隔符** @param datas list数据* @param func 处理list中每个元素的函数* @param separator 分隔符* @param <T> list中的数据类型* @return 处理后的string, 如果datas为空,默认返回null*/public static <T> String list2StrWithSeparator(List<T> datas, Function<T, String> func, String separator) {return Optional.ofNullable(datas).map(list -> list.stream().map(func).collect(Collectors.joining(separator))).orElse(null);}/*** map转list** @param datas map对象* @param func 处理map中每一对元素的函数* @param <K> key的类型* @param <V> value的类型* @param <R> 返回的list中元素类型* @return 转换后的list对象*/public static <K, V, R> List<R> map2List(Map<K, V> datas, BiFunction<K, V, R> func) {return Optional.ofNullable(datas).map(m -> m.entrySet().stream().map(me -> func.apply(me.getKey(), me.getValue())).collect(Collectors.toList())).orElse(null);}/*** 分组, 根据指定的key, 返回同一组实体对象** @param list 集合数据* @param keyFunc 获取key的方法* @param <K> key的类型* @param <T> 集合中的数据类型* @return 转换后的map或者不可变map*/public static <K, T> Map<K, List<T>> groupBy(List<T> list, Function<T, K> keyFunc) {return Optional.ofNullable(list).map(tl -> tl.stream().collect(Collectors.groupingBy(keyFunc))).orElse(new HashMap<>(0));}/*** 根据某个 key 进行分组,并将两个不同类型的值分别放入两个 List 中,返回 Map<K, Pair<List<V1>, List<V2>>>** @param items 输入的列表* @param keyMapper 用于获取 key 的方法* @param value1Mapper 用于获取第一个 List 值的映射方法* @param value2Mapper 用于获取第二个 List 值的映射方法* @param <K> 分组的 key 类型* @param <V> 输入的列表项类型* @param <V1> 第一个 List 的值类型* @param <V2> 第二个 List 的值类型* @return Map<K, Pair < List < V1>, List<V2>>> 格式的数据*/public static <K, V, V1, V2> Map<K, Pair<List<V1>, List<V2>>> groupBy(List<V> items, Function<V, K> keyMapper,Function<V, V1> value1Mapper, Function<V, V2> value2Mapper) {// 创建一个 Map,用于存储结果Map<K, Pair<List<V1>, List<V2>>> resultMap = new HashMap<>();// 遍历输入的 items 列表for (V item : items) {// 通过 keyMapper 获取分组 keyK key = keyMapper.apply(item);// 使用 computeIfAbsent 确保每个 key 对应一个 Pair<List<V1>, List<V2>>Pair<List<V1>, List<V2>> pair =resultMap.computeIfAbsent(key, k -> Pair.of(new ArrayList<>(), new ArrayList<>()));// 将第一个值加入 Pair 的第一个 List 中pair.getKey().add(value1Mapper.apply(item));// 将第二个值加入 Pair 的第二个 List 中pair.getValue().add(value2Mapper.apply(item));}// 返回结果 Mapreturn resultMap;}/*** 两层次分组的通用方法,生成 Map<K1, Map<K2, V2>> 格式的结果 根据 keyMapper1 和 keyMapper2 分别对列表中的元素进行分组,并将元素映射到 valueMapper 中,最后使用* resultCollector 收集结果** @param items 输入的列表* @param keyMapper1 第一层分组的 key 提取器* @param keyMapper2 第二层分组的 key 提取器* @param valueMapper 用于将列表项映射成最终的值* @param <V> 输入的列表项类型* @param <K1> 第一层分组的 key 类型* @param <K2> 第二层分组的 key 类型* @param <V2> 第二次分组的值类型* @param <V3> 最终映射的值类型* @return Map<K1, Map < K2, V2>> 分组后的结果*/public static <V, K1, K2, V2, V3> Map<K1, Map<K2, V3>> multiLevelGroupBy(List<V> items, Function<V, K1> keyMapper1,Function<V, K2> keyMapper2, Function<V, V2> valueMapper, Collector<V2, ?, V3> resultCollector) {if (items == null) {return new HashMap<>(0);}return items.stream().collect(Collectors.groupingBy(keyMapper1,Collectors.groupingBy(keyMapper2, Collectors.mapping(valueMapper, resultCollector))));}/*** 多个key组成对象的map; 例如 {k1&&k2, [v1,v2]},{k1&&k3, [v1,v2]}*/public static <T, K> Map<String, List<T>> groupByMultiKey(List<T> list, Function<T, K>... keyFuncs) {if (list == null) {return new HashMap<>(0);}if (keyFuncs == null || keyFuncs.length == 0) {return new HashMap<>(0);}return list.stream().collect(Collectors.groupingBy(e -> Stream.of(keyFuncs).map(keyFunc -> keyFunc.apply(e) + "").collect(Collectors.joining(DEFAULT_CONNECTOR_CHAR))));}/*** 先对每一条元素执行consumer操作 然后根据指定的key分组** @param list 待处理的list* @param consumer 执行的consumer* @param keyFunc 获取key的方法* @param <K> key的类型* @param <T> 集合中的数据类型* @return 转换后的map或者不可变map*/public static <K, T> Map<K, List<T>> consumerAndGroupBy(List<T> list, Consumer<T> consumer,Function<T, K> keyFunc) {return Optional.ofNullable(list).map(tl -> tl.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(item -> {consumer.accept(item); // 执行副作用操作return item;}, Collectors.toList())))).orElse(new HashMap<>(0));}/*** 分组求和** @param list 待处理的list* @param keyFunc 获取key的方法* @param sumFieldKey 需要求和的字段* @param <K> 分组字段的类型* @param <T> 数据类型* @return 分组求和的结果*/public static <K, T> Map<K, BigDecimal> groupAndSum(List<T> list, Function<T, K> keyFunc, Function<T, BigDecimal> sumFieldKey) {if (CollectionUtils.isEmpty(list)) {return new HashMap<>(0);}return list.stream().collect(Collectors.groupingBy(keyFunc,Collectors.reducing(BigDecimal.ZERO, sumFieldKey, BigDecimal::add)));}/*** 分组, 根据指定的key, 返回同一组value** @param list 集合数据* @param keyFunc 获取key的方法* @param valFunc 获取value的方法* @param <K> key的类型* @param <T> 集合中的数据类型* @param <V> value的类型* @return*/public static <K, T, V> Map<K, List<V>> groupBy(List<T> list, Function<T, K> keyFunc, Function<T, V> valFunc) {return Optional.ofNullable(list).map(tl -> tl.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valFunc, Collectors.toList())))).orElse(new HashMap<>(0));}/*** 嵌套分组, 将list集合中的数据按照某个键值进行分组,再按照另一个键值进行分组,返回嵌套的map对象, 类似与group by k1,k2** @param list 需要分组的集合* @param keyExtractor1 分组键值1* @param keyExtractor2 分组键值2* @param <T> 集合中元素类型* @param <K1> 第一层分组的键值类型* @param <K2> 第二层分组的键值类型* @return*/public static <T, K1, K2> Map<K1, Map<K2, List<T>>> nestedGroupBy(List<T> list, Function<T, K1> keyExtractor1,Function<T, K2> keyExtractor2) {return Optional.ofNullable(list).map(tl -> tl.stream().collect(Collectors.groupingBy(keyExtractor1, Collectors.groupingBy(keyExtractor2)))).orElse(new HashMap<>(0));}/*** 嵌套分组, 将list集合中的数据按照某个键值进行分组,再按照另一个键值进行分组,再按照另一个键值进行分组,返回嵌套的map对象, 类似与group by k1,k2,k3** @param list 需要分组的集合* @param classifier1 第一层分组的键值类型* @param classifier2 第二层分组的键值类型* @param classifier3 第三层分组的键值类型*/public static <T, K1, K2, K3> Map<K1, Map<K2, Map<K3, List<T>>>> nestedGroupingBy(List<T> list,Function<T, K1> classifier1, Function<T, K2> classifier2, Function<T, K3> classifier3) {return Optional.ofNullable(list).map(tl -> tl.stream().collect(Collectors.groupingBy(classifier1, Collectors.groupingBy(classifier2, Collectors.groupingBy(classifier3))))).orElse(new HashMap<>(0));}/*** bigDecimal求和, 过滤掉了空值*/public static BigDecimal sumBigDecimal(List<BigDecimal> numbers) {return Optional.ofNullable(numbers).map(list -> list.stream().filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)).orElse(BigDecimal.ZERO);}/*** 根据key分组求和*/public static <T> BigDecimal sumBigDecimalByKey(List<T> list, Function<T, BigDecimal> keyExtractor) {return Optional.ofNullable(list).map(tl -> tl.stream().map(keyExtractor).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)).orElse(BigDecimal.ZERO);}/*** 按照对象的某个属性进行升序排序** @param list 待排序的对象列表* @param keyExtractor 提取排序键的函数* @param <T> 对象类型* @param <U> 排序键类型*/public static <T, U extends Comparable<? super U>> void sortBy(List<T> list, Function<T, U> keyExtractor) {Optional.ofNullable(list).ifPresent(tl -> tl.sort(Comparator.comparing(keyExtractor)));}/*** 按照对象的某个属性进行降序排序** @param list 待排序的对象列表* @param keyExtractor 提取排序键的函数* @param <T> 对象类型* @param <U> 排序键类型*/public static <T, U extends Comparable<? super U>> void sortByDesc(List<T> list, Function<T, U> keyExtractor) {Optional.ofNullable(list).ifPresent(tl -> tl.sort(Comparator.comparing(keyExtractor).reversed()));}/*** 多属性排序:支持多条件的排序,按照第一个属性排序,然后是第二个属性,以此类推** @param list 待排序的对象列表* @param keyExtractors 排序键提取函数列表* @param <T> 对象类型*/@SafeVarargs@SuppressWarnings("unchecked")public static <T> void sortByMulti(List<T> list, Function<T, ? extends Comparable<?>>... keyExtractors) {if (list == null || keyExtractors.length == 0) {return;}Comparator<T> comparator = null;for (Function<T, ? extends Comparable<?>> keyExtractor : keyExtractors) {if (comparator == null) {comparator = Comparator.comparing((Function<T, Comparable<Object>>) keyExtractor);} else {comparator = comparator.thenComparing((Function<T, Comparable<Object>>) keyExtractor);}}list.sort(comparator);}/*** 多属性降序排序:支持多条件的降序排序,按照第一个属性降序排序,然后是第二个属性,以此类推** @param list 待排序的对象列表* @param keyExtractors 排序键提取函数列表* @param <T> 对象类型*/@SafeVarargs@SuppressWarnings("unchecked")public static <T> void sortByMultiDesc(List<T> list, Function<T, ? extends Comparable<?>>... keyExtractors) {if (list == null || keyExtractors.length == 0) {return;}Comparator<T> comparator = null;for (Function<T, ? extends Comparable<?>> keyExtractor : keyExtractors) {if (comparator == null) {comparator =Comparator.comparing((Function<T, Comparable<Object>>) keyExtractor, Comparator.reverseOrder());} else {comparator =comparator.thenComparing((Function<T, Comparable<Object>>) keyExtractor, Comparator.reverseOrder());}}list.sort(comparator);}/*** 多属性排序:支持多条件的排序, 可以指定某个条件升序还是降序, 按照第一个属性排序,然后是第二个属性,以此类推*/public static <T> void sortByRules(List<T> list,Pair<Function<T, ? extends Comparable<?>>, Boolean>... keyExtractors) {if (list == null || keyExtractors.length == 0) {return;}Comparator<T> comparator = null;for (Pair<Function<T, ? extends Comparable<?>>, Boolean> pair : keyExtractors) {if (comparator == null) {comparator =Comparator.comparing((Function<T, Comparable<Object>>) pair.getLeft(), getSortRule(pair.getRight()));} else {comparator = comparator.thenComparing((Function<T, Comparable<Object>>) pair.getLeft(),getSortRule(pair.getRight()));}}list.sort(comparator);}private static <T extends Comparable<? super T>> Comparator<T> getSortRule(boolean asc) {if (asc) {return Comparator.naturalOrder();} else {return Comparator.reverseOrder();}}
}