Java 谓词所有非空字段

Java 谓词所有非空字段,java,java-stream,predicate,Java,Java Stream,Predicate,我有一个简单的Book类,它包含如下字段 private String ISBN; private String title; private String author; 我想创建一个搜索查询,它将把BookDto作为条件,并将所有不可为空的字段与我的列表的元素进行比较。所以我写了几个简单的谓词 private Predicate<Book> matchingAuthor(Book another) { return book -> book.getAuthor()

我有一个简单的
Book
类,它包含如下字段

private String ISBN;
private String title;
private String author;
我想创建一个搜索查询,它将把
BookDto
作为条件,并将所有不可为空的字段与我的
列表的元素进行比较。所以我写了几个简单的
谓词

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());
}
私有谓词匹配作者(预订另一个){
return book->book.getAuthor()!=null&&book.getAuthor().equals(另一个.getAuthor());
}
私有谓词匹配标题(另一本书){
return book->book.getTitle()!=null&&book.getTitle().equals(另一个.getTitle());
}
私有谓词匹配ISBN(另一本书){
return book->book.getISBN()!=null&&book.getISBN().equals(另一个.getISBN());
}
我想要一个能处理所有逻辑的搜索方法

private List<BookDto> findMatchingBooks(BookDto criteria) {
        return books.stream().map(BookConverter::toEntity).filter(this::matchingBook).map(BookConverter::toDto).collect(Collectors.toList());
}
private List findMatchingBooks(BookDto标准){
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(criteria.getISBN()!=null){
返回匹配ISBN(标准);
} 
else if(criteria.getISBN()==null&&criteria.getTitle()==null&&criteria.getAuthor()!=null){
返回匹配作者(标准);
}
else if(criteria.getISBN()==null&&criteria.getTitle()!=null&&criteria.getAuthor()!=null){
返回匹配作者(标准)和匹配标题(标准);
}
}
前两个
if/else
是ok(丑陋但有效),第三个是

二进制运算符“&&”的操作数类型错误 第一类:谓词 第二类:谓词


问题是,我如何才能做到这一点

您需要使用以下命令组合谓词:

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

必须使用组合
谓词

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


default Predicate and(Predicate)如何在
Book
类本身中添加一些布尔方法,例如
boolean hasSameAuthor(Book other)
?旁白:返回books.stream().map(BookConverter::toEntity).filter(this::matchingBook).map(BookConverter::toDto).collect(collector.toList())的内容并不十分清楚
正在执行。
如何筛选(此::matchingBook)
使用当前签名?还请注意您的
matchingBook
方法中缺少一个返回值。可以将其定义为true,如
return book->true;
只是一种预感,您可能正在寻找一个简单的链接或条件来逐个匹配属性,或者返回false。例如:
matchingISBN(标准)。或者(matchingAuthor(criteria))。或(matchingTitle(criteria));
您的条件是多余的。当您执行
if(criteria.getISBN()!=null){…}
时,您不需要
else if(criteria.getISBN())==null…
,因为此时它必须是
null
。这同样适用于其他条件。此方法甚至不会编译,因为编译器不识别冗余,并且会说最后必须有另一个
返回值
。只需使用
返回标准。getISBN()!=null?匹配ISBN(标准):criteria.getTitle()==null?matchingAuthor(criteria):matchingAuthor(criteria).and(matchingTitle(criteria));
关于它应该是什么逻辑,或者。1)匹配isbn或者2)匹配author…@swinkler:你从哪里得到的?也许我误读了MatchingBook方法,它声明:如果isbn存在,返回isbn谓词。或者:如果author(并且只有author)存在,返回作者谓词…为什么和?因为
return matchingAuthor(criteria)&&matchingTitle(criteria)
。如果两者都存在,则两者必须匹配。当然。这是最后一个条件。我以前写过这两个条件。
return matchingAuthor(criteria).and(matchingTitle(criteria));