Home > database >  How to handle null if an element may not exist when returning from List<> method
How to handle null if an element may not exist when returning from List<> method

Time:10-08

I have this method:

public static List<PointElement> retrievePoints(
    FullResponse responseWrapper) {
  List<PointElement> pointsList =
      responseWrapper.getFullBreakdownResult().getPoints();
  return pointsList.stream()
      .map(
          point ->
              new PointElement(
                  null,
                  null,
                  point.getRefNum(),
                  point.getPointCode()))
      .collect(Collectors.toList());
  }
}

It's possible that pointsList might be a null value. Currently if that's the case I get a NullPointerException at the return.

I thought maybe I could change it to:

public static Optional<List<PointElement>> retrievePoints(
    FullResponse responseWrapper) {
  Optional<List<PointElement>> pointsList =
      responseWrapper.getFullBreakdownResult().getPoints();
  return pointsList.stream()
      .map(
          point ->
              new PointElement(
                  null,
                  null,
                  point.getRefNum(),
                  point.getPointCode()))
      .collect(Collectors.toList());
  }
}

That causes other issues in that methods point.getRefNum() and point.getPointCode() cannot be resolved?

How do I resolve this issue?

CodePudding user response:

Optional<Collection<T>> is generally frowned upon. Return an empty collection instead.

public static List<PointElement> retrievePoints(
    FullResponse responseWrapper) {
  List<PointElement> pointsList =
      responseWrapper.getFullBreakdownResult().getPoints();
  if (pointsList == null) return Collections.emptyList();

  return pointsList.stream()
      .map(
          point ->
              new PointElement(
                  null,
                  null,
                  point.getRefNum(),
                  point.getPointCode()))
      .collect(Collectors.toList());
  }
}

CodePudding user response:

May be you need filter the data inside in your stream, using filter is perfect for this case.

        public static List<PointElement> retrievePoint(FullResponse responseWrapper){
        List<PointElement> pointsList = responseWrapper.getFullBreakdownResult().getPoints();
        if(pointsList == null)return Collections.emptyList();
        return pointsList.stream().filter(point -> points!=null).map(point ->newPointElement(null,null,point.getRefNum(),point.getPointCode())).collections(Collectors.toList());
        }

If you prefer use Objects from java.util, to validate if a Object is null, like:

if(Objects.isNull(pointsList)) return Collections.emptyList();

And you can use in a stream like:

return list.stream().filter(e-> Objects.nonNull(e)).collect(Collectors.toList());

Or

return list.stream().filter(Objects::nonNull).collect(Collectors.toList());

CodePudding user response:

As @knittl has pointed out in his answer, wrapping a Collection with an Optional doesn't make sense.

Optional was designed as a container of nullable data, and you can safely interact with the container regardless whether it contains a value or not. But Collections and arrays by their nature are also containers of data, they can represent the absence of data by being empty and that can be verified without any issues.

Therefore, List would be sufficient as a return value.

Since you're not treating the case when responseWrapper.getFullBreakdownResult().getPoints() doesn't return a data as a normal event and not going to throw an exception or log this information, then you can use Java 9 method Stream.ofNullable() to generate a stream pipeline from the nullable source.

public static List<PointElement> retrievePoints(FullResponse responseWrapper) {
    
    return Stream.ofNullable(responseWrapper.getFullBreakdownResult().getPoints())
        .map(point ->
                new PointElement(
                    null,
                    null,
                    point.getRefNum(),
                    point.getPointCode())
        )
        .toList(); // for Java 16 or collect(Collectors.toList())
}
  • Related