Для каждого критерия вы можете иметь BiPredicate<String, Message>
1 , который принимает необработанный ввод от пользователя и сообщение и сообщает, соответствует ли сообщение опции фильтрации 2 .
Map<String, BiPredicate<String, Message>> criteria = Map.of(
"title", (userTitle, message) -> input.equals(message.getTitle())
...
);
Я приведу вам упрощенный пример использования этой карты:
Scanner scanner = new Scanner(System.in);
String filteringOption = scanner.nextLine();
String userInput = scanner.nextLine();
BiPredicate<String, Message> predicate = criteria.get(filteringOption);
// get all messages from the storage
getAll()
// make a stream out of them
.stream()
// apply the filtering rule from the map
.filter(m -> predicate.test(userInput, m))
// collect them into a list to display
.collect(Collectors.toList());
Позже эти предикаты могут быть объединены с помощью логических операций, таких как or()
, and()
, для формирования пользовательской опции фильтра. Пользовательская опция может быть добавлена на карту для последующих вызовов или рассчитана на лету каждый раз, когда пользователь запрашивает ее, например
BiPredicate<String, Message> titleAndDateFilter =
criteria.get("title").and(criteria.get("date"));
1 Вы можете использовать Predicate<Message>
, но это сделает эти функции менее изолированными, поскольку вам нужно сравнить контекст сообщения с заданным вводом.
2 Я использовал Java 9's Map.of
.