Reputation: 557
I'm having simple Book
class that contains fields like
private String ISBN;
private String title;
private String author;
I want to create search query, that will take BookDto
as criteria, and compare all non nullable fields with elements of my List<Book>
. So I wrote few simple Predicates
private Predicate<Book> matchingAuthor(Book another) {
return book -> book.getAuthor() != null && book.getAuthor().equals(another.getAuthor());
}
private Predicate<Book> matchingTitle(Book another) {
return book -> book.getTitle() != null && book.getTitle().equals(another.getTitle());
}
private Predicate<Book> matchingISBN(Book another) {
return book -> book.getISBN() != null && book.getISBN().equals(another.getISBN());
}
And I'd like to have 1 search method that will handle all the logic
private List<BookDto> findMatchingBooks(BookDto criteria) {
return books.stream().map(BookConverter::toEntity).filter(this::matchingBook).map(BookConverter::toDto).collect(Collectors.toList());
}
But this logic is ugly... and it wont work as I want.
private Predicate<Book> matchingBook(Book criteria) {
if(criteria.getISBN() != null) {
return matchingISBN(criteria);
}
else if(criteria.getISBN() == null && criteria.getTitle() == null && criteria.getAuthor() != null) {
return matchingAuthor(criteria);
}
else if(criteria.getISBN() == null && criteria.getTitle() != null && criteria.getAuthor() != null) {
return matchingAuthor(criteria) && matchingTitle(criteria);
}
}
First two if/else
are lets say ok (ugly but working), third one is causing
bad operand types for binary operator '&&' first type: Predicate second type: Predicate
And the question is, how can I achieve this?
Upvotes: 1
Views: 1635
Reputation: 12819
You must use Predicate::and
to combine the Predicates
:
return matchingAuthor(criteria).and(matchingTitle(criteria));
default Predicate<T> and(Predicate<? super T> other)
:
Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another. When evaluating the composed predicate, if this predicate is false, then the other predicate is not evaluated. Any exceptions thrown during evaluation of either predicate are relayed to the caller; if evaluation of this predicate throws an exception, the other predicate will not be evaluated.
Upvotes: 1