我有一个对象列表,比如car
。我想使用Java 8根据某些参数过滤这个列表。但是如果参数是null
,它会抛出NullPointerException
异常。如何过滤掉空值?
当前代码如下
requiredCars = cars.stream().filter(c -> c.getName().startsWith("M"));
如果getName()
返回null
,则会抛出NullPointerException
。
我有一个对象列表,比如car
。我想使用Java 8根据某些参数过滤这个列表。但是如果参数是null
,它会抛出NullPointerException
异常。如何过滤掉空值?
当前代码如下
requiredCars = cars.stream().filter(c -> c.getName().startsWith("M"));
如果getName()
返回null
,则会抛出NullPointerException
。
Optional.ofNullable
,因为Optional的东西确实是用于返回类型而不是用于执行逻辑...但实际上这些都不重要。我想指出,在一个广泛的情况下,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());
Objects::nonNull
不能在这里使用,在最后的建议中应该是 cars.stream().filter(car -> Objects.nonNull(car.getName()))
。我相信。 - kiedysktoscars.stream() .filter(car -> Objects.nonNull(car.getName()) && car.getName().startsWith("M"))
会是你在这个问题上的建议总结。 - kiedysktos.startWith
也可能导致空指针异常。我想表达的是,Java提供了一种特定的方法来过滤掉流中的空对象。 - xbakesxObjects.nonNull
等同于 != null
,你的选项更短。 - kiedysktosString
),而不是汽车对象列表(Car
)? - user1803551您只需要筛选出名称为null
的汽车:
requiredCars = cars.stream()
.filter(c -> c.getName() != null)
.filter(c -> c.getName().startsWith("M"));
提出的答案很好。只是想建议一种改进方法,使用Java 8中的Optional.ofNullable
处理null
列表的情况,这是一个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
您可以在单个筛选器步骤中完成此操作:
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());
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())
;
你可以使用这个
List<Car> requiredCars = cars.stream()
.filter (t-> t!= null && StringUtils.startsWith(t.getName(),"M"))
.collect(Collectors.toList());