Java Reference
In-Depth Information
If we want to add a star after the title if the topic is featured, we will start by needing to define what
it means to “add a star after the title.” Given our available API for the Book class, we will have to define an
inline lambda to do this. (This is a sign that our Book API is probably missing something useful, but that is
another conversation.) Thinking functionally, we want to apply a transformation when certain criterion is
true. This calls for another utility function: applyIf . That will take a predicate and a function, and apply the
function only when the predicate is true. Since we are only working with a single data type, we can use the
UnaryOperator shorthand to save some typing and some type variables. With that utility method available to
us, we then need to get a handle on a Predicate to determine if the topic is featured, as well as the function
to perform the transformation. The resulting UnaryOperator does exactly what we are looking for: if the
Predicate test returns true , we will execute our “add a star after the title” function; if the test returns false ,
we will return the Book instance we were provided. The code for this approach is given in Listing 3-5.
Listing 3-5. A Library instance method to star featured books using List.replaceAll
/**
* Applies a mapping operation to the argument only when {@code test}
* returns {@code true} for that argument.
*
* @param test Test determining if mapping is applied; never {@code null}
* @param ifTrue Mapping to apply when the test is true; never {@code null}
* @return Operator appling {@code ifTrue} when {@code test} is true
* and otherwise returning the argument.
*/
private static <T> UnaryOperator<T> applyIf(
Predicate<T> test, UnaryOperator<T> ifTrue
) {
Objects.requireNonNull(test, "the predicate to test");
Objects.requireNonNull(ifTrue, "the method to apply if true");
return t -> {
if(test.test(t)) {
return ifTrue.apply(t);
} else {
return t;
}
};
}
/**
* Updates the library, replacing each book that is featured with a book
* with the same title plus {@code *}.
*/
public void starFeatureBooks() {
UnaryOperator<Book> starBook = book ->
new Book(book.getTitle() + "*", book.getAuthor(), book.getGenre());
Predicate<Book> isFeatured = getFeaturedBooks().keySet()::contains;
UnaryOperator<Book> starIfFeatured = applyIf(isFeatured, starBook);
getBooks().replaceAll(starIfFeatured);
}
Search WWH ::




Custom Search