仅当在Java8中使用lambda时不为null时才过滤值

时间:2015-10-01 09:36:22

标签: java lambda nullpointerexception null java-8

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

目前的代码如下

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

如果NullPointerException返回getName(),则会引发null

6 个答案:

答案 0 :(得分:266)

在这个特定的例子中,我认为@Tagir是100%正确的,将它放入一个过滤器并进行两次检查。我不会使用Optional.ofNullable可选的东西真的是返回类型不做逻辑......但实际上既不在这里也不在那里。

我想指出java.util.Objects在一个广泛的案例中有一个很好的方法,所以你可以这样做:

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

这将清除您的null对象。对于不熟悉的人来说,这是以下方面的缩写:

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());

答案 1 :(得分:44)

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

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

答案 2 :(得分:35)

建议的答案很棒。我想建议使用Optional.ofNullablenew feature in 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

答案 3 :(得分:19)

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

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());

答案 4 :(得分:4)

利用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())
;

答案 5 :(得分:0)

您可以使用此

List<Car> requiredCars = cars.stream()
    .filter (t->  t!= null && StringUtils.startsWith(t.getName(),"M"))
    .collect(Collectors.toList());