Explain Codes LogoExplain Codes Logo

Filter values only if not null using lambda in Java8

java
lambda
stream-processing
null-safety
Anton ShumikhinbyAnton Shumikhin·Oct 29, 2024
TLDR

Utilize Objects::nonNull in tandem with Stream#filter to eradicate nulls:

List<String> noNulls = list.stream().filter(Objects::nonNull).collect(Collectors.toList());

As a result, noNulls will only contain non-null entities.

Now, let's roll up our sleeves and dive deeper into Java 8 lambdas and streams for efficient and clean null handling.

How to handle compound conditions and chain filters

To eliminate nulls and apply additional conditions, you can chain multiple filters:

List<Car> filteredCars = cars.stream() .filter(Objects::nonNull) // Not taking any hitchhikers .filter(car -> car.getColor().equals("Red")) // Only red cars, please .collect(Collectors.toList());

This way, you end up with non-null cars, racy and red.

Leveraging shortcuts for list processing

If you've ever felt like obj -> obj != null is too verbose, transform the lambda into method reference (Objects::nonNull):

Robust attribute validations: no more NPEs

Beware of object attributes! To ward off NullPointerException, properly check for nulls:

List<String> carNames = cars.stream() .filter(Objects::nonNull) .filter(car -> car.getName() != null) // Be sure that car has a name before using it .map(Car::getName) // The transformation spell .collect(Collectors.toList());

This will give you a list of car names, and only the named ones will be invited.

Tips to handle null collections gracefully

When your list could potentially be null, resort to Optional.ofNullable with orElseGet:

List<String> safeList = Optional.ofNullable(list) .orElseGet(Collections::emptyList) // Better safe than sorry .stream() .filter(Objects::nonNull) .collect(Collectors.toList());

Boom! Here's your null-safe list processing!

String filtering techniques for GitHub Ninjas

When it comes to string-specific cases, StringUtils makes your life easier:

List<String> nonEmptyNames = names.stream() .filter(StringUtils::isNotBlank) // Only the chatty ones can pass .collect(Collectors.toList());

This makes use of the StringUtils class from Apache Commons Lang to filter out any zombie strings (null or empty)!

Large data processing with streams

Process large collections like a boss 🕶️, using streams:

  • Lazy operations: Operations like filter wait until the last minute (lazy!), and only run when necessary.
  • Short-circuiting: Certain operations like findAny leave the office early and don't process the entire stream.
  • Parallel Processing: Parallel streams split the work, showing multi-core power (Stream Team Assemble!)

Protect your nested properties

Here's how to make sure that nested attributes that could be null don't cause trouble:

List<String> ownerNames = cars.stream() .filter(car -> car.getOwner() != null && car.getOwner().getName() != null) // Double protection because why not? .map(car -> car.getOwner().getName()) .collect(Collectors.toList());

Ensuring that both Owner and Owner's Name are non-null before processing, because Safety First!

Coding Saga: Stream operations and method chaining

With the power of filter, map, and collect, you can create a fluent pipeline for data processing:

  • Filter: Play the bouncer and keep unruly elements out.
  • Map: Transform the guests to suit the party.
  • Collect: Gather everyone in the club (result collection).

The ingredients for an Effective Lambdajian

  • Keep it simple: Combine all necessary conditions in a single filter.
  • Less is more: Minimize method calling within streams.
  • Reach for the toolbox: For strings, toys like Apache Commons Lang or Google Guava provide lighting talks and nerd delights