问题

发现Collectors.toMap的一个坑,key可以为null,但value不能为null,否则抛空指针异常nullPointerException。这可真是反直觉。

原因

在这里插入图片描述

解决方案

方案一

使用Optional类处理value,优点是可以继续使用Collectors.toMap,缺点是为null的value会被改,而这可能违反业务上的期望。

方案二

使用 Stream#collect(java.util.function.Supplier<R>, java.util.function.BiConsumer<R,? super T>, java.util.function.BiConsumer<R,R>)方法,可以保留为null的value。所以个人推荐方案二。

两个方案的代码如下:

public class TestCollect {

  static class User {

    String userName;
    String idCard;

    public String getUserName() {
      return userName;
    }


    public String getIdCard() {
      return idCard;
    }

    public User(String userName, String idCard) {
      this.userName = userName;
      this.idCard = idCard;
    }

  }

  public static void main(String[] args) {
    User user01 = new User("user01", "000000001");
    User user02 = new User("user02", "000000002");
    User user03 = new User("user03", "000000003");
    User user04 = new User(null, "000000004");
    User user05 = new User("user05", null);
    User user06 = new User("user05", "a");
    User user07 = new User("user05", "b");
    ArrayList<User> list = new ArrayList();
    list.add(user01);
    list.add(user02);
    list.add(user03);
    list.add(user04);
    list.add(user05);
    list.add(user06);
    list.add(user07);

    /**
     * key可以为null, value不可以为null
     */
//    HashMap<String, String> map01 = list.stream().collect(
//        Collectors.toMap(User::getUserName, User::getIdCard, (a, b) -> b, HashMap::new));
//    System.out.println(map01);

    //解决方案一,使用Optional类处理null
    HashMap<String, String> map02 = list.stream().collect(Collectors
        .toMap(User::getUserName, s -> Optional.ofNullable(s.getIdCard()).orElse("空的"), (a, b) -> b,
            HashMap::new));
    System.out.println(map02);

    //解决方案二,直接使用collect()方法进行规约操作
    HashMap<String, String> map03 = list.stream()
        .collect(HashMap::new, (map, item) -> map.put(item.getUserName(), item.getIdCard()),
            HashMap::putAll);
    System.out.println(map03);

  }
}


主要参考: Stream使用Collector.tomap方法value值为null时报空指针异常 解决方案

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐