谓词所有非空字段



我有一个简单的Book类,其中包含以下字段

private String ISBN;
private String title;
private String author;

我想创建搜索查询,该查询将以BookDto为条件,并将所有不可为空的字段与我的List<Book>元素进行比较。所以我写了几个简单的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());
}

我希望有 1 种搜索方法可以处理所有逻辑

private List<BookDto> findMatchingBooks(BookDto criteria) {
return books.stream().map(BookConverter::toEntity).filter(this::matchingBook).map(BookConverter::toDto).collect(Collectors.toList());
}

但这种逻辑是丑陋的...它不会像我想要的那样工作。

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

前两个if/else让我们说OK(丑陋但有效(,第三个是导致

二元运算符"&&"的错误操作数类型 第一种类型:谓语 第二种类型:谓语

问题是,我怎样才能做到这一点?

你需要使用and组合你的谓词:

return matchingAuthor(criteria).and(matchingTitle(criteria));

返回一个组合谓词,该谓词表示此谓词和另一个谓词的短路逻辑 AND。

您必须使用Predicate::and来组合Predicates

return matchingAuthor(criteria).and(matchingTitle(criteria));
<小时 />

default Predicate<T> and(Predicate<? super T> other)

返回一个组合谓词,该谓词表示此谓词和另一个谓词的短路逻辑 AND。在计算组合谓词时,如果此谓词为 false,则不计算另一个谓词。 在任一谓词的求值期间引发的任何异常都将中继给调用方;如果此谓词的计算引发异常,则不会计算另一个谓词。