Why does findFirst() throw a NullPointerException if the first element it finds is null?

后端 未结 5 912
被撕碎了的回忆
被撕碎了的回忆 2020-11-28 08:39

Why does this throw a java.lang.NullPointerException?

List strings = new ArrayList<>();
        strings.add(null);
        s         


        
5条回答
  •  無奈伤痛
    2020-11-28 08:55

    As already discussed, the API designers do not assume that the developer wants to treat null values and absent values the same way.

    If you still want to do that, you may do it explicitly by applying the sequence

    .map(Optional::ofNullable).findFirst().flatMap(Function.identity())
    

    to the stream. The result will be an empty optional in both cases, if there is no first element or if the first element is null. So in your case, you may use

    String firstString = strings.stream()
        .map(Optional::ofNullable).findFirst().flatMap(Function.identity())
        .orElse(null);
    

    to get a null value if the first element is either absent or null.

    If you want to distinguish between these cases, you may simply omit the flatMap step:

    Optional firstString = strings.stream()
        .map(Optional::ofNullable).findFirst().orElse(null);
    System.out.println(firstString==null? "no such element":
                       firstString.orElse("first element is null"));
    

    This is not much different to your updated question. You just have to replace "no such element" with "StringWhenListIsEmpty" and "first element is null" with null. But if you don’t like conditionals, you can achieve it also like:

    String firstString = strings.stream().skip(0)
        .map(Optional::ofNullable).findFirst()
        .orElseGet(()->Optional.of("StringWhenListIsEmpty"))
        .orElse(null);
    

    Now, firstString will be null if an element exists but is null and it will be "StringWhenListIsEmpty" when no element exists.

提交回复
热议问题