只有在Java8中使用lambda不为null的情况下才会过滤值

我有一个对象列表说car 。 我想根据使用Java 8的一些参数来过滤这个列表。但是如果参数为null ,则会抛出NullPointerException 。 如何过滤出空值?

目前的代码如下

 requiredCars = cars.stream().filter(c -> c.getName().startsWith("M")); 

如果getName()返回null则抛出NullPointerException

在这个特定的例子中,我认为@Tagir是100%正确的,把它放到一个filter中,并做两次检查。 我不会使用Optional.ofNullable可选的东西是真正的返回types不是做逻辑…但真的既不在这里也不在那里。

我想指出java.util.Objects在大范围内有一个很好的方法,所以你可以这样做:

 cars.stream() .filter(Objects::nonNull) 

这将清除你的空对象。 对于任何不熟悉的人来说,这就是以下几点:

 cars.stream() .filter(car -> Objects.nonNull(car)) 

要完全回答手头的问题,返回名称为"M"的汽车列表:

 cars.stream() .filter(car -> Objects.nonNull(car)) .map(car -> car.getName()) .filter(carName -> Objects.nonNull(carName)) .filter(carName -> carName.startsWith("M")) .collect(Collectors.toList()); 

一旦你习惯了速记lambda,你也可以这样做:

 cars.stream() .filter(Objects::nonNull) .map(Car::getName) // Assume the class name for car is Car .filter(Objects::nonNull) .filter(carName -> carName.startsWith("M")) .collect(Collectors.toList()); 

您可以在单个过滤步骤中执行此操作:

 requiredCars = cars.stream().filter(c -> c.getName() != null && c.getName().startsWith("M")); 

如果您不想多次调用getName() (例如,调用昂贵的代码),则可以这样做:

 requiredCars = cars.stream().filter(c -> { String name = c.getName(); return name != null && name.startsWith("M"); }); 

或者以更复杂的方式:

 requiredCars = cars.stream().filter(c -> Optional.ofNullable(c.getName()).filter(name -> name.startsWith("M")).isPresent()); 

build议的答案很好。 只是想提出一个改进来处理空列表的情况下使用Optional.ofNullable , 在Java 8的新function :

  List<String> carsFiltered = Optional.ofNullable(cars) .orElseGet(Collections::emptyList) .stream() .filter(Objects::nonNull) .collect(Collectors.toList()); 

所以,完整的答案是:

  List<String> carsFiltered = Optional.ofNullable(cars) .orElseGet(Collections::emptyList) .stream() .filter(Objects::nonNull) //filtering car object that are null .map(Car::getName) //now it's a stream of Strings .filter(Objects::nonNull) //filtering null in Strings .filter(name -> name.startsWith("M")) .collect(Collectors.toList()); //back to List of Strings 

您只需要过滤名称为null的汽车:

 requiredCars = cars.stream() .filter(c -> c.getName() != null) .filter(c -> c.getName().startsWith("M"));