愿景:简化 Stream 操作,代码优雅++

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;

/**
 * @desc Stream流处理工具(完善版:加强null安全、一致性,并添加平均/排序/分区功能)
 *       所有方法默认过滤源集合中的null元素,返回空集合而非null,避免NPE。
 */
public class StreamUtils {

    /**
     * 转换map,获取本身,去重,对象、key忽略null。
     *
     * @param source      源集合(Collection<T>),输入数据源
     * @param keyFunction 获取key的函数(Function<T, K>),用于提取map的key
     * @return Map<K, T>  转换后的map,key重复时保留最后value;若源空,返回空HashMap
     */
    public static <T, K> Map<K, T> toMap(Collection<T> source, Function<T, K> keyFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .collect(Collectors.toMap(keyFunction, Function.identity(), (v1, v2) -> v2));
    }

    /**
     * 转换map,获取本身,去重,对象、key忽略null,并应用额外过滤。
     *
     * @param source      源集合(Collection<T>),输入数据源
     * @param keyFunction 获取key的函数(Function<T, K>),用于提取map的key
     * @param predicate   过滤条件(Predicate<? super T>),额外过滤源元素
     * @return Map<K, T>  转换后的map,key重复时保留最后value;若源空,返回空HashMap
     */
    public static <T, K> Map<K, T> toMap(Collection<T> source, Function<T, K> keyFunction, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .filter(predicate)
                .collect(Collectors.toMap(keyFunction, Function.identity(), (v1, v2) -> v2));
    }

    /**
     * 转换map,去重,对象、key、value忽略null。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param keyFunction  获取key的函数(Function<T, K>),用于提取map的key
     * @param valueFunction 获取value的函数(Function<T, V>),用于提取map的value
     * @return Map<K, V>   转换后的map,key重复时保留最后value;若源空,返回空HashMap
     */
    public static <T, K, V> Map<K, V> toMap(Collection<T> source, Function<T, K> keyFunction, Function<T, V> valueFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .filter(obj -> Objects.nonNull(valueFunction.apply(obj)))
                .collect(Collectors.toMap(keyFunction, valueFunction, (v1, v2) -> v2));
    }

    /**
     * 转换map,去重,对象、key、value忽略null,支持自定义合并。
     *
     * @param source        源集合(Collection<T>),输入数据源
     * @param keyFunction   获取key的函数(Function<T, K>),用于提取map的key
     * @param valueFunction 获取value的函数(Function<T, V>),用于提取map的value
     * @param mergeFunction 合并函数(BinaryOperator<V>),key重复时的value合并逻辑
     * @return Map<K, V>    转换后的map,使用mergeFunction处理重复;若源空,返回空HashMap
     */
    public static <T, K, V> Map<K, V> toMap(Collection<T> source, Function<T, K> keyFunction, Function<T, V> valueFunction, BinaryOperator<V> mergeFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(obj -> Objects.nonNull(keyFunction.apply(obj)))
                .filter(obj -> Objects.nonNull(valueFunction.apply(obj)))
                .collect(Collectors.toMap(keyFunction, valueFunction, mergeFunction));
    }

    /**
     * 转换map,去重,使用map重新put方式(优化:统一用toMap,过滤value null)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param keyFunction  获取key的函数(Function<T, K>),用于提取map的key
     * @param valueFunction 获取value的函数(Function<T, V>),用于提取map的value
     * @return HashMap<K, V> 转换后的HashMap,key重复时保留最后value;若源空,返回空HashMap
     */
    public static <T, K, V> HashMap<K, V> toMap2(Collection<T> source, Function<T, K> keyFunction, Function<T, V> valueFunction) {
        return (HashMap<K, V>) toMap(source, keyFunction, valueFunction, (v1, v2) -> v2);  // 复用toMap,确保一致性
    }

    /**
     * 转换为List,应用映射函数。
     *
     * @param source   源集合(Collection<T>),输入数据源
     * @param function 映射函数(Function<T, R>),转换每个元素
     * @return List<R> 转换后的List,可能包含null;若源空,返回空ArrayList
     */
    public static <T, R> List<R> toList(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(function)
                .collect(Collectors.toList());
    }

    /**
     * 转换为List,应用映射函数,忽略null结果。
     *
     * @param source   源集合(Collection<T>),输入数据源
     * @param function 映射函数(Function<T, R>),转换每个元素
     * @return List<R> 转换后的List,不含null;若源空,返回空ArrayList
     */
    public static <T, R> List<R> toListIgnoreNull(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(function)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 转换为Set,应用映射函数。
     *
     * @param source   源集合(Collection<T>),输入数据源
     * @param function 映射函数(Function<T, R>),转换每个元素
     * @return Set<R>  转换后的HashSet,可能包含null;若源空,返回空HashSet
     */
    public static <T, R> Set<R> toSet(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(function)
                .collect(Collectors.toSet());
    }

    /**
     * 转换为Set,应用映射函数,忽略null结果。
     *
     * @param source   源集合(Collection<T>),输入数据源
     * @param function 映射函数(Function<T, R>),转换每个元素
     * @return Set<R>  转换后的HashSet,不含null;若源空,返回空HashSet
     */
    public static <T, R> Set<R> toSetIgnoreNull(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(function)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
    }

    /**
     * 转换为LinkedHashSet,应用映射函数,忽略null结果。
     *
     * @param source   源集合(Collection<T>),输入数据源
     * @param function 映射函数(Function<T, R>),转换每个元素
     * @return LinkedHashSet<R> 转换后的LinkedHashSet,不含null,保持插入顺序;若源空,返回空LinkedHashSet
     */
    public static <T, R> LinkedHashSet<R> toLinkedHashSet(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newLinkedHashSet();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(function)
                .filter(Objects::nonNull)
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }

    /**
     * 转换为LinkedList,应用映射函数,忽略null结果。
     *
     * @param source   源集合(Collection<T>),输入数据源
     * @param function 映射函数(Function<T, R>),转换每个元素
     * @return LinkedList<R> 转换后的LinkedList,不含null;若源空,返回空LinkedList
     */
    public static <T, R> LinkedList<R> toLinkedList(Collection<T> source, Function<T, R> function) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newLinkedList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(function)
                .filter(Objects::nonNull)
                .collect(Collectors.toCollection(LinkedList::new));
    }

    /**
     * 将集合分组,遇到重复的key,value放入集合中。
     *
     * @param source      源集合(Collection<V>),输入数据源
     * @param keyFunction 获取key的函数(Function<? super V, ? extends K>),用于分组key
     * @return Map<K, List<V>> 分组后的map,value为List;若源空,返回空HashMap
     */
    public static <K, V> Map<K, List<V>> groupToMap(Collection<V> source, Function<? super V, ? extends K> keyFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(s -> Objects.nonNull(keyFunction.apply(s)))
                .collect(Collectors.groupingBy(keyFunction));
    }

    /**
     * 将集合分组,遇到重复的key,value放入集合中(LinkedHashMap 保持顺序)。
     *
     * @param source      源集合(Collection<V>),输入数据源
     * @param keyFunction 获取key的函数(Function<? super V, ? extends K>),用于分组key
     * @return LinkedHashMap<K, List<V>> 分组后的LinkedHashMap,value为List,保持插入顺序;若源空,返回空LinkedHashMap
     */
    public static <K, V> LinkedHashMap<K, List<V>> groupToLinkedHashMap(Collection<V> source, Function<? super V, ? extends K> keyFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newLinkedHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(s -> Objects.nonNull(keyFunction.apply(s)))
                .collect(Collectors.groupingBy(keyFunction, LinkedHashMap::new, Collectors.toList()));
    }

    /**
     * 将集合分组,遇到重复的key,并统计重复key的次数。
     *
     * @param source      源集合(Collection<V>),输入数据源
     * @param keyFunction 获取key的函数(Function<? super V, ? extends K>),用于分组key
     * @return Map<K, Long> 分组后的map,value为计数;若源空,返回空HashMap
     */
    public static <K, V> Map<K, Long> groupToMapCount(Collection<V> source, Function<? super V, ? extends K> keyFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(s -> Objects.nonNull(keyFunction.apply(s)))
                .collect(Collectors.groupingBy(keyFunction, Collectors.counting()));
    }

    /**
     * 过滤集合,返回List。
     *
     * @param source    源集合(Collection<T>),输入数据源
     * @param predicate 过滤条件(Predicate<? super T>),保留满足条件的元素
     * @return List<T>  过滤后的List;若源空,返回空ArrayList
     */
    public static <T> List<T> filter(Collection<T> source, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate)
                .collect(Collectors.toList());
    }

    /**
     * 过滤Set,返回Set。
     *
     * @param set       源Set(Set<T>),输入数据源
     * @param predicate 过滤条件(Predicate<? super T>),保留满足条件的元素
     * @return Set<T>   过滤后的HashSet;若源空,返回空HashSet
     */
    public static <T> Set<T> filter(Set<T> set, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(set)) {
            return Sets.newHashSet();
        }
        return set.stream()
                .filter(Objects::nonNull)
                .filter(predicate)
                .collect(Collectors.toCollection(HashSet::new));
    }

    /**
     * 过滤集合,返回LinkedHashSet。
     *
     * @param source    源集合(Collection<T>),输入数据源
     * @param predicate 过滤条件(Predicate<? super T>),保留满足条件的元素
     * @return LinkedHashSet<T> 过滤后的LinkedHashSet,保持顺序;若源空,返回空LinkedHashSet
     */
    public static <T> LinkedHashSet<T> filterToSet(Collection<T> source, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newLinkedHashSet();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate)
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }

    /**
     * 过滤集合,返回Stream。
     *
     * @param source    源集合(Collection<T>),输入数据源
     * @param predicate 过滤条件(Predicate<? super T>),保留满足条件的元素
     * @return Stream<T> 过滤后的Stream;若源空,返回空Stream
     */
    public static <T> Stream<T> filterStream(Collection<T> source, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(source)) {
            return Stream.empty();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate);
    }

    /**
     * 过滤集合,返回Stream(双过滤条件)。
     *
     * @param source     源集合(Collection<T>),输入数据源
     * @param predicate1 第一过滤条件(Predicate<? super T>),第一个过滤
     * @param predicate2 第二过滤条件(Predicate<? super T>),第二个过滤
     * @return Stream<T> 过滤后的Stream;若源空,返回空Stream
     */
    public static <T> Stream<T> filterStream(Collection<T> source, Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
        if (CollectionUtils.isEmpty(source)) {
            return Stream.empty();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate1)
                .filter(predicate2);
    }

    /**
     * 过滤并映射,返回List。
     *
     * @param source      源集合(Collection<T>),输入数据源
     * @param predicate   过滤条件(Predicate<? super T>),保留满足条件的元素
     * @param mapFunction 映射函数(Function<T, R>),转换每个元素
     * @return List<R>    过滤映射后的List,可能包含null;若源空,返回空ArrayList
     */
    public static <T, R> List<R> filterMapList(Collection<T> source, Predicate<? super T> predicate, Function<T, R> mapFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate)
                .map(mapFunction)
                .collect(Collectors.toList());
    }

    /**
     * 过滤并映射,返回List(双过滤条件)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param predicate1   第一过滤条件(Predicate<? super T>),第一个过滤
     * @param predicate2   第二过滤条件(Predicate<? super T>),第二个过滤
     * @param mapFunction  映射函数(Function<T, R>),转换每个元素
     * @return List<R>     过滤映射后的List,可能包含null;若源空,返回空ArrayList
     */
    public static <T, R> List<R> filterMapList(Collection<T> source, Predicate<? super T> predicate1, Predicate<? super T> predicate2, Function<T, R> mapFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate1)
                .filter(predicate2)
                .map(mapFunction)
                .collect(Collectors.toList());
    }

    /**
     * 过滤并映射,返回Set。
     *
     * @param source      源集合(Collection<T>),输入数据源
     * @param predicate   过滤条件(Predicate<? super T>),保留满足条件的元素
     * @param mapFunction 映射函数(Function<T, R>),转换每个元素
     * @return Set<R>     过滤映射后的HashSet,可能包含null;若源空,返回空HashSet
     */
    public static <T, R> Set<R> filterMapSet(Collection<T> source, Predicate<? super T> predicate, Function<T, R> mapFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate)
                .map(mapFunction)
                .collect(Collectors.toSet());
    }

    /**
     * 过滤并映射,返回Set(双过滤条件)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param predicate1   第一过滤条件(Predicate<? super T>),第一个过滤
     * @param predicate2   第二过滤条件(Predicate<? super T>),第二个过滤
     * @param mapFunction  映射函数(Function<T, R>),转换每个元素
     * @return Set<R>      过滤映射后的HashSet,可能包含null;若源空,返回空HashSet
     */
    public static <T, R> Set<R> filterMapSet(Collection<T> source, Predicate<? super T> predicate1, Predicate<? super T> predicate2, Function<T, R> mapFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return Sets.newHashSet();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .filter(predicate1)
                .filter(predicate2)
                .map(mapFunction)
                .collect(Collectors.toSet());
    }

    /**
     * 从eList中设置字段值到vList中(优化:检查v key null)。
     *
     * @param vList        v对象集合(Collection<V>),目标集合,需要设置值的对象
     * @param eList        e对象集合(Collection<E>),源集合,提供值的对象
     * @param keyFunctionE e对象获取key方法(Function<E, R>),从e提取key
     * @param keyFunctionV v对象获取key方法(Function<V, R>),从v提取key
     * @param consumer     赋值转换方法(BiConsumer<V, E>),设置v字段的逻辑(v, e)
     */
    public static <V, E, R> void setVFromE(Collection<V> vList, Collection<E> eList, Function<E, R> keyFunctionE,
                                           Function<V, R> keyFunctionV,
                                           BiConsumer<V, E> consumer) {
        if (CollectionUtils.isNotEmpty(eList)) {
            Map<R, E> map = StreamUtils.toMap(eList, keyFunctionE);
            vList.stream()
                    .filter(Objects::nonNull)
                    .filter(v -> Objects.nonNull(keyFunctionV.apply(v)))  // 新增:防v key null
                    .forEach(v -> {
                        E e = map.get(keyFunctionV.apply(v));
                        if (Objects.nonNull(e)) {
                            consumer.accept(v, e);
                        }
                    });
        }
    }

    /**
     * 从eList中设置集合项字段值到vList中的集合项属性(优化:检查v key null)。
     *
     * @param vList        v对象集合(Collection<V>),目标集合,需要设置值的对象
     * @param eList        e对象集合(Collection<E>),源集合,提供值的对象
     * @param keyFunctionE e对象获取key方法(Function<E, R>),从e提取key
     * @param keyFunctionV v对象获取key方法(Function<V, R>),从v提取key
     * @param consumer     赋值转换方法(BiConsumer<V, List<E>>),设置v集合字段的逻辑(v, List<e>)
     */
    public static <V, E, R> void setVListFromE(Collection<V> vList, Collection<E> eList, Function<E, R> keyFunctionE,
                                              Function<V, R> keyFunctionV,
                                              BiConsumer<V, List<E>> consumer) {
        if (CollectionUtils.isNotEmpty(eList)) {
            Map<R, List<E>> map = StreamUtils.groupToMap(eList, keyFunctionE);
            vList.stream()
                    .filter(Objects::nonNull)
                    .filter(v -> Objects.nonNull(keyFunctionV.apply(v)))  // 新增:防v key null
                    .forEach(v -> {
                        List<E> e = map.get(keyFunctionV.apply(v));
                        if (Objects.nonNull(e)) {
                            consumer.accept(v, e);
                        }
                    });
        }
    }

    /**
     * 累加(优化:过滤value null,用Optional防NPE)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param valueFunction 获取BigDecimal字段(Function<T, BigDecimal>),提取数值
     * @return BigDecimal  所有值的累加和;若源空或无有效值,返回BigDecimal.ZERO
     * @param <T>          源元素类型
     */
    public static <T> BigDecimal add(Collection<T> source, Function<T, BigDecimal> valueFunction) {
        if (CollectionUtils.isEmpty(source)) {
            return BigDecimal.ZERO;
        }
        return source.stream()
                .filter(Objects::nonNull)
                .map(valueFunction)
                .filter(Objects::nonNull)  // 新增:防value null
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 累加并设置四舍五入(保留newScale位小数)(优化:过滤value null)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param valueFunction 获取BigDecimal字段(Function<T, BigDecimal>),提取数值
     * @param newScale     小数位数(int),保留位数
     * @return BigDecimal  累加和,四舍五入后结果;若源空或无有效值,返回BigDecimal.ZERO
     * @param <T>          源元素类型
     */
    public static <T> BigDecimal addHalfUp(Collection<T> source, Function<T, BigDecimal> valueFunction, int newScale) {
        if (CollectionUtils.isEmpty(source)) {
            return BigDecimal.ZERO;
        }
        return add(source, valueFunction).setScale(newScale, RoundingMode.HALF_UP);
    }

    /**
     * 累加并设置四舍五入(保留2位小数)(优化:过滤value null)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param valueFunction 获取BigDecimal字段(Function<T, BigDecimal>),提取数值
     * @return BigDecimal  累加和,四舍五入后结果(2位);若源空或无有效值,返回BigDecimal.ZERO
     * @param <T>          源元素类型
     */
    public static <T> BigDecimal addHalfUp(Collection<T> source, Function<T, BigDecimal> valueFunction) {
        return addHalfUp(source, valueFunction, 2);
    }

    /**
     * 计算平均值(优化:过滤value null,四舍五入)。
     *
     * @param source       源集合(Collection<T>),输入数据源
     * @param valueFunction 获取BigDecimal字段(Function<T, BigDecimal>),提取数值
     * @param scale        小数位数(int),保留位数
     * @return BigDecimal  平均值,四舍五入后结果;若源空或无有效值,返回BigDecimal.ZERO
     * @param <T>          源元素类型
     */
    public static <T> BigDecimal average(Collection<T> source, Function<T, BigDecimal> valueFunction, int scale) {
        if (CollectionUtils.isEmpty(source)) {
            return BigDecimal.ZERO;
        }
        BigDecimal sum = add(source, valueFunction);
        long count = source.stream()
                .filter(Objects::nonNull)
                .filter(t -> Objects.nonNull(valueFunction.apply(t)))  // 一致过滤
                .count();
        return count == 0 ? BigDecimal.ZERO : sum.divide(BigDecimal.valueOf(count), scale, RoundingMode.HALF_UP);
    }

    /**
     * 转换为排序列表。
     *
     * @param source     源集合(Collection<T>),输入数据源
     * @param comparator 比较器(Comparator<? super T>),排序规则
     * @return List<T>   排序后的List;若源空,返回空ArrayList
     * @param <T>        元素类型
     */
    public static <T> List<T> toSortedList(Collection<T> source, Comparator<? super T> comparator) {
        if (CollectionUtils.isEmpty(source)) {
            return Lists.newArrayList();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .sorted(comparator)
                .collect(Collectors.toList());
    }

    /**
     * 根据predicate分区:true/false -> List。
     *
     * @param source    源集合(Collection<T>),输入数据源
     * @param predicate 分区条件(Predicate<? super T>),true/false分组
     * @return Map<Boolean, List<T>> 分区map,key为Boolean,value为对应List;若源空,返回空HashMap
     * @param <T>       元素类型
     */
    public static <T> Map<Boolean, List<T>> partitionToMap(Collection<T> source, Predicate<? super T> predicate) {
        if (CollectionUtils.isEmpty(source)) {
            return Maps.newHashMap();
        }
        return source.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.partitioningBy(predicate));
    }

    /**
     * 根据key去重(返回Predicate)。
     *
     * @param keyExtractor 提取key函数(Function<? super T, K>),用于去重判断
     * @return Predicate<T> 去重过滤器
     * @param <T>           元素类型
     * @param <K>           key类型
     */
    public static <T, K> Predicate<T> distinctByKey(Function<? super T, K> keyExtractor) {
        Set<K> seen = new HashSet<>();  // 优化:单线程用HashSet,减少开销
        return t -> {
            K key = keyExtractor.apply(t);
            if (Objects.isNull(key)) {
                return false;  // 新增:忽略key null
            }
            return seen.add(key);
        };
    }

    /**
     * 根据key去重,返回List。
     *
     * @param list        源List(List<T>),输入数据源
     * @param keyExtractor 提取key函数(Function<? super T, K>),用于去重判断
     * @return List<T>    去重后的List,保留首次出现的元素;若源空,返回空List
     * @param <T>         元素类型
     * @param <K>         key类型
     */
    public static <T, K> List<T> distinctByKey(List<T> list, Function<? super T, K> keyExtractor) {
        return list.stream()
                .filter(distinctByKey(keyExtractor))
                .collect(Collectors.toList());
    }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐