Java8之Stream之List转Map有哪些坑

2021-09-09 13:45:20 浏览数 (1)

Duplicate key 问题

当 key 值重复时会有这个问题,异常如下

代码语言:javascript复制
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 小C
	at java.util.stream.Collectors.lambda$throwingMerger$0(Unknown Source)
	at java.util.HashMap.merge(Unknown Source)
	at java.util.stream.Collectors.lambda$toMap$58(Unknown Source)
	at java.util.stream.ReduceOps$3ReducingSink.accept(Unknown Source)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.collect(Unknown Source)
	at JavaBase.lamda.List2Map.main(List2Map.java:47)

Duplicate key 解决办法一:遇到重复的key就使用后者替换
代码语言:javascript复制
// 后面的值代替之前的值
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(value1 , value2)-> value2 ));
Duplicate key 解决办法二:重复时将前面的value和后面的value拼接起来
代码语言:javascript复制
// 重复时将前面的value 和后面的value拼接起来
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(value1 , value2)-> value1 "," value2 ));

Duplicate key 解决办法三:重复时将重复key的数据组成集合

代码语言:javascript复制
// 重复时将重复key的数据组成集合
Map<String, List<String>> map = list.stream().collect(Collectors.toMap(Person::getId, p -> {
            List<String> getNameList = new ArrayList<>();
            getNameList.add(p.getName());
            return getNameList;
        }, (List<String> value1, List<String> value2) -> {
            value1.addAll(value2);
            return value1;
        }));
NullPointerException 问题
代码语言:javascript复制
Exception in thread "main" java.lang.NullPointerException
	at java.util.HashMap.merge(Unknown Source)
	at java.util.stream.Collectors.lambda$toMap$58(Unknown Source)
	at java.util.stream.ReduceOps$3ReducingSink.accept(Unknown Source)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.collect(Unknown Source)
	at JavaBase.lamda.List2Map.main(List2Map.java:47)

解决办法

代码语言:javascript复制
Map<String, String> map = (Map<String, String>) list.stream().collect(HashMap::new,(k, v) ->k.put(v.getId(),v.getName()),HashMap::putAll);
Map类集合Key/Value能否存储null值情况表格

集合类

Key

Value

Super

说明

ConcurrentHashMap

不允许为null

不允许为null

AbstractMap

分段锁技术

Hashtable

不允许为null

不允许为null

Dictionary

线程安全

HashMap

允许为null

允许为null

AbstractMap

线程不安全

TreeMap

不允许为null

允许为null

AbstractMap

线程不安全

完整测试代码

代码语言:javascript复制
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    private String id;
    private String name;
    public Person(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

public class List2Map {

    public static void main(String[] args) {
        // 声明一个List集合
        List<Person> list = new ArrayList();
        list.add(new Person("1001", "小A"));
        list.add(new Person("1002", "小B"));
        list.add(new Person("1003", "小C"));
//        list.add(new Person("1003", "小D"));
        list.add(new Person("1004", null));
//        list.add(new Person(null, "小D"));
        // 将list转换map
        Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName));
        // 后面的值代替之前的值
//        Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(value1 , value2)-> value2 ));
        // 重复时将前面的value 和后面的value拼接起来
//        Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(value1 , value2)-> value1 "," value2 ));
        // 重复时将重复key的数据组成集合
      /*  Map<String, List<String>> map = list.stream().collect(Collectors.toMap(Person::getId, p -> {
            List<String> getNameList = new ArrayList<>();
            getNameList.add(p.getName());
            return getNameList;
        }, (List<String> value1, List<String> value2) -> {
            value1.addAll(value2);
            return value1;
        }));*/
        
//        Map<String, String> map = (Map<String, String>) list.stream().collect(HashMap::new,(k, v) ->k.put(v.getId(),v.getName()),HashMap::putAll);
        System.out.println(map);
    }
}

欢迎关注公众号:程序员财富自由之路

0 人点赞