我有一个对象列表,比如汽车。我想使用Java 8根据某些参数筛选这个列表。但如果参数为空,则抛出NullPointerException。如何过滤空值?
当前代码如下
requiredCars = cars.stream().filter(c -> c.getName().startsWith("M"));
如果getName()返回null,则抛出NullPointerException。
我有一个对象列表,比如汽车。我想使用Java 8根据某些参数筛选这个列表。但如果参数为空,则抛出NullPointerException。如何过滤空值?
当前代码如下
requiredCars = cars.stream().filter(c -> c.getName().startsWith("M"));
如果getName()返回null,则抛出NullPointerException。
你只需要过滤那些有空名字的车:
requiredCars = cars.stream()
.filter(c -> c.getName() != null)
.filter(c -> c.getName().startsWith("M"));
你可以在一个过滤步骤中做到这一点:
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());
在这个特殊的例子中,我认为@Tagir是100%正确的,让它进入一个过滤器,并进行两次检查。我不会使用Optional。ofNullable这个可选的东西实际上是为了返回类型而不是做逻辑…但其实不是这里,也不是那里。
我想指出的是,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());
不幸的是,一旦你。map(Car::getName),你将只返回名字的列表,而不是汽车。虽然不太漂亮,但完全回答了这个问题:
cars.stream()
.filter(car -> Objects.nonNull(car))
.filter(car -> Objects.nonNull(car.getName()))
.filter(car -> car.getName().startsWith("M"))
.collect(Collectors.toList());
提议的答案很棒。只是想建议一个改进,以处理空列表使用可选的情况。nullable, Java 8的新特性:
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
你可以用这个
List<Car> requiredCars = cars.stream()
.filter (t-> t!= null && StringUtils.startsWith(t.getName(),"M"))
.collect(Collectors.toList());
利用java.util.Optional#map()的功能:
List<Car> requiredCars = cars.stream()
.filter (car ->
Optional.ofNullable(car)
.map(Car::getName)
.map(name -> name.startsWith("M"))
.orElse(false) // what to do if either car or getName() yields null? false will filter out the element
)
.collect(Collectors.toList())
;