Предикат все не пустые поля - PullRequest
1 голос
/ 27 сентября 2019

У меня есть простой 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 - допустим, нормально (некрасиво, но работает), третий вызывает

неверные типы операндов для двоичного оператора '&&' первый тип: предикатвторой тип: предикат

И вопрос в том, как этого добиться?

Ответы [ 3 ]

1 голос
/ 27 сентября 2019

Вы должны использовать Predicate::and, чтобы объединить Predicates:

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

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

Возвращает составной предикат, который представляет короткое замыкание логического И этого предиката и другого.При оценке составного предиката, если этот предикат равен false, то другой предикат не оценивается.Любые исключения, сгенерированные во время оценки любого предиката, передаются вызывающей стороне;если оценка этого предиката вызывает исключение, другой предикат не будет оцениваться.

1 голос
/ 27 сентября 2019

Вам необходимо объединить свои предикаты, используя and:

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

Возвращает составной предикат, который представляет собой короткое замыкание логического И этого предиката и другого.

0 голосов
/ 27 сентября 2019

Из

return matchingAuthor(criteria) && matchingTitle(criteria);

сделать это

return matchingAuthor(criteria).and(matchingTitle(criteria));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...