简体   繁体   中英

Java Streams checking for nulls

I want to convert this piece code into streams

List<ECSUSU> listOfUSUs = msccRequest.getUsedServiceUnit();
if (listOfUSUs != null) {
     ECSUSU usedServiceUnit = listOfUSUs.get(0);
     if (usedServiceUnit.getCcTime() != null && usedServiceUnit.getCcTime() > 0) {
          return UnitType.SECONDS;
      } else {
          return UnitType.BYTES;
      }
}

I would thought this will work but I am getting NullPointerException. msccRequest.getUsedServiceUnit() might return null , that's why I need the check

 msccRequest.getUsedServiceUnit().stream()
                    .filter(list -> list != null)
                    .limit(1)
                    .map(usedServiceUnit -> {
                        if (usedServiceUnit.getCcTime() != null && usedServiceUnit.getCcTime() > 0) {
                            return UnitType.SECONDS;
                        } else {
                            return UnitType.BYTES;
                        }
                    });

filter applies to individual elements of the Stream (A Stream iterates over each element in the list), so if msccRequest.getUsedServiceUnit() returns null , the .stream() invocation will throw an NPE. If you need to ensure that the list itself is not null , I suggest that you wrap it in an Optional , like this:

Optional<List<ECSUSU>> list = Optional.ofNullable(msccRequest.getUsedServiceUnit())

Then use ifPresent to implement the iteration:

list.ifPresent(notNullListForSure -> notNullListForSure.stream())

etc

If msccRequest.getUsedServiceUnit() returns null , the attempt to call the stream() method on that will throw a NullPointerException . I expect the NPE comes from that. You need to check for null before calling the stream() method.

Also note that your two pieces of code are not equivalent (even if the above problem is fixed). The first code only checks the first element of the list, while the second takes the first non-null element.

Also, you are only interested in a single element of the list. Then findFirst seems to be a better choice than limit .

List<ECSUSU> listOfUSUs = msccRequest.getUsedServiceUnit();
if (listOfUSUs != null) {
    return listOfUSUs.stream()
        .filter(Objects::nonNull)
        .findFirst()
        .map(usedServiceUnit -> {
                if (usedServiceUnit.getCcTime() != null && usedServiceUnit.getCcTime() > 0) {
                    return UnitType.SECONDS;
                } else {
                    return UnitType.BYTES;
                }
            })
        .orElse(/* default value */);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM