自定义list To HashMap工具类

简介: 自定义list To HashMap工具类

没有比正直更富的遗产。——莎士比亚

我们在使用JDK自带的Collectors.toMap时,可能会遇到如下问题(什么?你不知道toMap干嘛的?戳我了解):

1.key重复,出现java.lang.IllegalStateException: Duplicate key ***异常

例如:

List<User> users = new ArrayList<>(Arrays.asList(new User(null, "HiNo"), new User(null, "SuPa")));
Map<String, String> map = users.stream().collect(Collectors.toMap(User::getUsername, User::getPassword));

2.value为空,出现NPE: java.lang.NullPointerException

例如:

List<User> users = new ArrayList<>(Arrays.asList(new User("SuPa", null), new User("HiNo", null)));
Map<String, String> map = users.stream().collect(Collectors.toMap(User::getUsername, User::getPassword));

这里我们可以不使用Collectors,而是直接在collect中传入参数

Map<String, String> map = users.stream().collect(HashMap::new, (m, v) -> m.put(v.getUsername(), v.getPassword()), HashMap::putAll);

或者是在后面追加参数,例如我这篇博客

这样确实可以解决,但每次都要写这一长串,有点难受——本人比较懒,所以写一个工具类

这里是直接put进去,所以不存在说key重复或者为NPE问题

import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
import com.ruben.pojo.User;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
/**
 * @ClassName: FunctionUtils
 * @Description: 我还没有写描述
 * @Date: 2020/11/9 0009 23:43
 * *
 * @author: <achao1441470436@gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
public class FunctionUtils {
    /**
     * @MethodName: toHashMap
     * @Description: list -> hashMap
     * @Date: 2021/1/31 0031 16:17
     * *
     * @author: <achao1441470436@gmail.com>
     * @param: [list, keyFunction, valueFunction]
     * @returnValue: java.util.Map<K, U>
     */
    public static <T, K, U> Map<K, U> toHashMap(List<T> list, Function<T, K> keyFunction, Function<T, U> valueFunction) {
        if (Objects.isNull(list) || list.isEmpty()) {
            return new HashMap<>(0);
        }
        return list.stream().collect(MyCollectors.toHashMap(keyFunction, valueFunction));
    }
    public static <T, K> Map<K, T> toHashMap(List<T> list, Function<T, K> keyFunction) {
        return toHashMap(list, keyFunction, null);
    }
    public static <T> Map<?, T> toHashMap(List<T> list) {
        return toHashMap(list, null, null);
    }
    /**
     * @ClassName: MyCollectors
     * @Date: 2020/12/4 0004 11:16
     * @Description: 我的自定义Collectors
     * @Author: <achao1441470436@gmail.com>
     */
    public static class MyCollectors {
        /**
         * @MethodName: toHashMap
         * @Description: 转换成hashmap
         * @Date: 2020/12/4 0004 13:39
         * *
         * @author: <achao1441470436@gmail.com>
         * @param: [methodName]
         * @returnValue: java.util.stream.Collector
         */
        public static <T, K, U> Collector<T, HashMap<K, U>, HashMap<K, U>> toHashMap(Function<T, K> keyFunction, Function<T, U> valueFunction) {
            return new MyCollectorImpl<>(HashMap::new, (m, v) -> m.put(Optional.ofNullable(keyFunction).map(keyF -> keyF.apply(v)).orElseGet(() -> {
                try {
                    return (K) v.getClass().getMethod("getId").invoke(v);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                }
                return null;
            }), Optional.ofNullable(valueFunction).map(valueF -> valueF.apply(v)).orElse((U) v)), (u, v) -> null, i -> i, Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)));
        }
        public static class MyCollectorImpl<T, A, R> implements Collector<T, A, R> {
            private final Supplier<A> supplier;
            private final BiConsumer<A, T> accumulator;
            private final BinaryOperator<A> combiner;
            private final Function<A, R> finisher;
            private final Set<Characteristics> characteristics;
            MyCollectorImpl(Supplier<A> supplier,
                            BiConsumer<A, T> accumulator,
                            BinaryOperator<A> combiner,
                            Function<A, R> finisher,
                            Set<Characteristics> characteristics) {
                this.supplier = supplier;
                this.accumulator = accumulator;
                this.combiner = combiner;
                this.finisher = finisher;
                this.characteristics = characteristics;
            }
            @Override
            public Supplier<A> supplier() {
                return supplier;
            }
            @Override
            public BiConsumer<A, T> accumulator() {
                return accumulator;
            }
            @Override
            public BinaryOperator<A> combiner() {
                return combiner;
            }
            @Override
            public Function<A, R> finisher() {
                return finisher;
            }
            @Override
            public Set<Characteristics> characteristics() {
                return characteristics;
            }
        }
    }
}

使用方式(注意返回值):

指定keyvalue使用它本身

Map<String, User> map = toHashMap(users, User::getUsername);

指定keyvalue

Map<String, String> map = toHashMap(users, User::getUsername, User::getPassword);

默认不指定,keyidvalue为它本身的方式(需要有id属性并包含getter

Map<?, User> map = toHashMap(users);
// 可以强转
Map<Integer, User> map = (Map<Integer, User>) toHashMap(users);
相关文章
|
JavaScript
Vue Antdv 列表(table、list)自定义空数据状态UI
Vue Antdv 列表(table、list)自定义空数据状态UI
683 0
|
SQL 前端开发 关系型数据库
mysql根据父节点递归查询所有子节点,List转树形结构工具类
mysql根据父节点递归查询所有子节点,List转树形结构工具类
1118 0
mysql根据父节点递归查询所有子节点,List转树形结构工具类
|
4月前
|
开发者 C# UED
WPF与多媒体:解锁音频视频播放新姿势——从界面设计到代码实践,全方位教你如何在WPF应用中集成流畅的多媒体功能
【8月更文挑战第31天】本文以随笔形式介绍了如何在WPF应用中集成音频和视频播放功能。通过使用MediaElement控件,开发者能轻松创建多媒体应用程序。文章详细展示了从创建WPF项目到设计UI及实现媒体控制逻辑的过程,并提供了完整的示例代码。此外,还介绍了如何添加进度条等额外功能以增强用户体验。希望本文能为WPF开发者提供实用的技术指导与灵感。
179 0
|
7月前
|
存储 安全 Java
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
53 0
|
Java
List集合处理工具类
List集合处理工具类
90 0
|
算法 C++ 容器
<C++> list容器本质|常用接口|自定义排序规则(下)
<C++> list容器本质|常用接口|自定义排序规则
116 0
|
Java
Java List操作好帮手:ListUtil工具类实用技巧
Java List操作好帮手:ListUtil工具类实用技巧
164 0
|
PHP
PHP - Laravel 查看自定义路由列表 (php artisan route:list)
PHP - Laravel 查看自定义路由列表 (php artisan route:list)
259 0
|
存储 C++ 容器
<C++> list容器本质|常用接口|自定义排序规则(上)
<C++> list容器本质|常用接口|自定义排序规则
120 0
pageable 使用自定义list实现分页
pageable 使用自定义list实现分页
143 0