对null值友好的Collectors.groupingBy

简介: 对null值友好的Collectors.groupingBy

一个人行走的范围,就是他的世界。——北岛

我们在使用Collectors.groupingBy时会遇到这种情况:

Map<String, List<User>> map = Arrays.asList(new User(), null).stream().collect(Collectors.groupingBy(User::getName));

为了避免这种情况,于是我自己实现了一个:

@SafeVarargs
@SuppressWarnings("unchecked")
public static <T, K, D, A, M extends Map<K, D>> M listGroupBy(List<T> list, Function<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks) {
    boolean hasFinished = downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH);
    return peekStream(list, isParallel, peeks).collect(new Collector<T, HashMap<K, A>, M>() {
        @Override
        public Supplier<HashMap<K, A>> supplier() {
            return HashMap::new;
        }
        @Override
        public BiConsumer<HashMap<K, A>, T> accumulator() {
            return (m, t) -> {
                K key = Optional.ofNullable(t).map(sFunction).orElse(null);
                A container = m.computeIfAbsent(key, k -> downstream.supplier().get());
                downstream.accumulator().accept(container, t);
            };
        }
        @Override
        public BinaryOperator<HashMap<K, A>> combiner() {
            return (m1, m2) -> {
                for (Map.Entry<K, A> e : m2.entrySet()) {
                    m1.merge(e.getKey(), e.getValue(), downstream.combiner());
                }
                return m1;
            };
        }
        @Override
        public Function<HashMap<K, A>, M> finisher() {
            return hasFinished ? i -> (M) i : intermediate -> {
                // a-> a[0]
                intermediate.replaceAll((k, v) -> (A) downstream.finisher().apply(v));
                @SuppressWarnings("unchecked")
                M castResult = (M) intermediate;
                return castResult;
            };
        }
        @Override
        public Set<Characteristics> characteristics() {
            return hasFinished ? Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)) : Collections.emptySet();
        }
    });
}

使用方式:

Map<String, List<User>> map = listGroupBy(Arrays.asList(new User(), null), User::getName, Collectors.toList(), false)

这样避免了抛出异常,返回了对null值友好的结果(map里包含一个keynull的结果)

我稍作修改放到MPSimpleQueryhutool中的CollStreamUtil以及CollectorUtil中去了

相关文章
使用JavaStream将List转为Map
使用JavaStream将List转为Map
|
自然语言处理 Java Go
ULID 在 Java 中的应用: 使用 `getMonotonicUlid` 生成唯一标识符
ULID 在 Java 中的应用: 使用 `getMonotonicUlid` 生成唯一标识符
503 0
|
存储 运维 NoSQL
Redis7.0 核心特性简介
Redis自 2009 年诞生以来,已经走过了 13 年。在这漫长的 13 年中,Redis 从小小的开源项目逐步演变成为当今最受欢迎的内存数据库之一,被用于多种场景,帮助解决很多问题
4158 0
Redis7.0 核心特性简介
|
SpringCloudAlibaba
SpringCloudAlibaba踩坑日记(二)Relying upon circular references is discouraged and they are prohibited by
SpringCloudAlibaba踩坑日记(二)Relying upon circular references is discouraged and they are prohibited by
4213 0
SpringCloudAlibaba踩坑日记(二)Relying upon circular references is discouraged and they are prohibited by
|
SQL 缓存 安全
深入解析MyBatis-Plus LambdaQueryWrapper与QueryWrapper:高效数据查询的秘密
深入解析MyBatis-Plus LambdaQueryWrapper与QueryWrapper:高效数据查询的秘密
13462 2
|
12月前
|
安全 Java 测试技术
如何在 Spring Boot 中禁用 Actuator 端点安全?
如何在 Spring Boot 中禁用 Actuator 端点安全?
2272 1
|
数据库 索引
联合索引和单独列有什么区别
【10月更文挑战第15天】联合索引和单独列有什么区别
616 2
|
JSON 负载均衡 Java
SpringCloud Feign 远程调用(史上最详细讲解)
SpringCloud Feign 远程调用(史上最详细讲解)
14304 0
SpringCloud Feign 远程调用(史上最详细讲解)
|
SQL Oracle 关系型数据库
实时计算 Flink版操作报错之遇到设置之后报错:java.sql.BatchUpdateException: ORA-01461:,如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
Java Python
【Python】已解决:ERROR: No matching distribution found for JPype
【Python】已解决:ERROR: No matching distribution found for JPype
917 0
下一篇
开通oss服务