234. Chaining lambdas via orElseFoo()

Some operations specific to lambda expressions return Optional (for example, findFirst(), findAny(), reduce(), and so on). Trying to address these Optional classes via the isPresent()-get() pair is a cumbersome solution because we have to break the chain of lambdas, add some conditional code via the if-else blocks, and consider resuming the chain.

The following snippet of code shows this practice:

private static final String NOT_FOUND = "NOT FOUND";

List<Book> books...;
...
// Avoid
public String findFirstCheaperBook(int price) {

Optional<Book> book = books.stream()
.filter(b -> b.getPrice()<price)
.findFirst();

if (book.isPresent()) {
return book.get().getName();
} else {
return NOT_FOUND;
}
}

One step further and we may have something like the following:

// Avoid
public String findFirstCheaperBook(int price) {

Optional<Book> book = books.stream()
.filter(b -> b.getPrice()<price)
.findFirst();

return book.map(Book::getName)
.orElse(NOT_FOUND);
}

Using orElse() instead of the isPresent()-get() pair is better. But it will be even better if we use orElse() (and orElseFoo()) directly in the chain of lambdas and avoid disrupted code:

private static final String NOT_FOUND = "NOT FOUND";
...
// Prefer
public String findFirstCheaperBook(int price) {

return books.stream()
.filter(b -> b.getPrice()<price)
.findFirst()
.map(Book::getName)
.orElse(NOT_FOUND);
}

Let's have one more problem.

This time, we have an author of several books, and we want to check whether a certain book was written by this author. If our author didn't write the given book, then we want to throw NoSuchElementException.

A really bad solution to this will be as follows:

// Avoid
public void validateAuthorOfBook(Book book) {
if (!author.isPresent() ||
!author.get().getBooks().contains(book)) {
throw new NoSuchElementException();
}
}

On the other hand, using orElseThrow() can solve the problem very elegantly:

// Prefer
public void validateAuthorOfBook(Book book) {
author.filter(a -> a.getBooks().contains(book))
.orElseThrow();
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.205.99