Java8之Stream之List转Map有哪些坑

简介: Java8之Stream之List转Map有哪些坑

Duplicate key 问题



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


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就使用后者替换


// 后面的值代替之前的值
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(value1 , value2)-> value2 ));

Duplicate key 解决办法二:重复时将前面的value和后面的value拼接起来


// 重复时将前面的value 和后面的value拼接起来
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(value1 , value2)-> value1+","+value2 ));

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

// 重复时将重复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 问题


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)

解决办法


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 线程不安全

完整测试代码



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);
    }
}


相关文章
|
2月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
2月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
233 100
|
2月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
266 101
|
2月前
|
并行计算 Java 大数据
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
240 101
|
3月前
|
存储 Java API
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
364 188
|
3月前
|
存储 Java API
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
271 92
|
1月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
158 1
|
4月前
|
Oracle Java 关系型数据库
掌握Java Stream API:高效集合处理的利器
掌握Java Stream API:高效集合处理的利器
387 80
|
4月前
|
安全 Java API
Java 8 Stream API:高效集合处理的利器
Java 8 Stream API:高效集合处理的利器
288 83
|
2月前
|
存储 数据可视化 Java
Java Stream API 的强大功能
Java Stream API 是 Java 8 引入的重要特性,它改变了集合数据的处理方式。通过声明式语法,开发者可以更简洁地进行过滤、映射、聚合等操作。Stream API 支持惰性求值和并行处理,提升了代码效率和可读性,是现代 Java 开发不可或缺的工具。
Java Stream API 的强大功能

热门文章

最新文章