it-swarm.com.de

Filtern Sie Werte nur, wenn sie in Java8 nicht null sind

Ich habe eine Liste von Objekten, die sagen car. Ich möchte diese Liste basierend auf einem Parameter mit Java 8 filtern. Wenn der Parameter jedoch null ist, wird NullPointerException ausgelöst. Wie filtere ich Nullwerte heraus?

Der aktuelle Code lautet wie folgt

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

Dies wirft NullPointerException, wenn getName()null zurückgibt.

140
vaibhavvc1092

In diesem speziellen Beispiel denke ich, dass @Tagir 100% korrekt ist, füge es in einen Filter ein und führe die beiden Überprüfungen durch. Ich würde Optional.ofNullable nicht verwenden. Das optionale Zeug ist wirklich für Rückgabetypen gedacht, die keine Logik betreiben ... aber wirklich weder hier noch dort.

Ich wollte darauf hinweisen, dass Java.util.Objects in einem weiten Fall eine gute Methode dafür hat, so dass Sie dies tun können:

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

Welches wird Ihre Null-Objekte löschen. Für jemanden, der nicht vertraut ist, ist das die Abkürzung für Folgendes:

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

So beantworten Sie die vorliegende Frage teilweise, um die Liste der Autonamen zurückzugeben, die mit "M" beginnt:

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

Sobald Sie sich an die Kurzschrift Lambdas gewöhnt haben, können Sie dies auch tun:

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

Sobald Sie .map(Car::getName) eingegeben haben, werden Sie leider nur die Liste der Namen zurückgeben, nicht die Autos. So weniger schön beantwortet aber voll die Frage:

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

Sie müssen nur die Autos filtern, die einen null -Namen haben:

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

Die vorgeschlagenen Antworten sind großartig. Ich möchte nur eine Verbesserung vorschlagen, um den Fall der Null-Liste mit der neuen Funktion Optional.ofNullablein Java 8 zu behandeln. :

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

Die vollständige Antwort lautet also:

 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
38
Johnny

Sie können dies in einem einzigen Filterschritt tun:

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

Wenn Sie getName() nicht mehrmals aufrufen möchten (zum Beispiel ein teurer Anruf), können Sie dies tun:

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

Oder auf raffiniertere Weise:

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

sie können dies verwenden

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

1
riverfan