#java #java-stream
Вопрос:
Java 11 здесь. У меня есть следующее POJO:
@Data // Lombok; adds getters, setters, all-args constructor and equals and hashCode public class Fliflam { private String merf; private String tarf; private Boolean isFlerf; }
У меня есть метод, который проверяет a Flimflam
и возвращает a Listlt;Stringgt;
любых ошибок, возникших при проверке Flimflam
. Я могу изменить это, чтобы вернуть Optionallt;Listlt;Stringgt;gt;
, если кто-то по какой-то причине сочтет это полезным, особенно при работе с потоковым API:
public Listlt;Stringgt; validateFlimflam(Flimflam flimflam) { Listlt;Stringgt; errors = new ArrayListlt;gt;(); // ... validation code omitted for brevity // 'errors' list is populated with any errors; otherwise it returns empty return errors; }
Я хочу передать поток (потоковый API) через a Listlt;Flimflamgt;
и заполнить Maplt;Flimflam,Listlt;Stringgt;gt;
карту ошибок, где ключом карты является a Flimflam
, который не прошел проверку, а его соответствующим значением является список строк ошибок проверки.
Я могу добиться этого «старомодным» способом, вот так:
Listlt;Flimflamgt; flimflams = getSomehow(); Maplt;Flimflam,Listlt;Stringgt;gt; errorsMap = new HashMaplt;gt;(); for (Flimflam ff : flimflams) { Listlt;Stringgt; errors = validateFlimflam(ff); if (!errors.isEmpty() { errorsMap.put(ff, errors); } }
Как я могу сделать это с помощью API Stream?
Комментарии:
1. Имело бы больше смысла использовать Vavr
Validation
?2. @hotmeatballsoup На самом деле, это не так. В нем не указывалось, где
validateFlimflam
объявлен метод (хотя можно было бы порассуждать). Важно точно знать, как применять любые лямбды или ссылки на методы. И, как ни странно, принятый ответ не работает, поскольку он синтаксически неверен. Но я не стал его понижать.3. Тогда вы или кто-то другой могли бы запросить это и дать мне возможность добавить больше деталей. Пища для размышлений.
Ответ №1:
Подобный этому
Maplt;Flimflam,Listlt;Stringgt;gt; errorsMap = flimflams.stream().collect(Collectors.toMap(f -gt; f, f-gt; f::validateFlimflam));
toMap
принимает 2 параметра (сопоставитель ключей,сопоставитель значений) В вашем случае сопоставитель ключей-это сам объект из потока, а значение вызывает validateFlimflam для этого объекта
Ответ №2:
Трудно сказать, где именно определен ваш validateFlimflam
метод. Я подозреваю, что это не в самом Flimflam
классе, так как не было бы необходимости передавать экземпляр самого себя методу. Поэтому я предполагаю, что это внешний метод для этого класса. Предполагая, что я буду действовать следующим образом:
Этот класс = экземпляр, содержащий validateFlimflam
. Может быть установлено значение this
Maplt;Flimflam, Listlt;Stringgt;gt; errorsMap = flimflams.stream().collect(Collectors.toMap(f -gt; f, thisClass::validateFlimflam));
Если случайно, Flimflam
действительно содержит validateFlimflam
, вы могли бы сделать это так. Обратите внимание, что это предполагает, что метод не принимает аргументов, так как в них нет необходимости
Maplt;Flimflam, Listlt;Stringgt;gt; errorsMap = flimflams.stream().collect(Collectors.toMap(f -gt; f, Flimflam::validateFlimflam));
Наконец, если содержащий класс является каким-то другим классом, а validateFlimflam
метод объявлен статическим, то вы можете сделать это так, используя имя содержащего класса, а не экземпляр. Кроме того, в этом случае метод будет принимать аргумент, как определено.
Maplt;Flimflam, Listlt;Stringgt;gt; errorsMap = flimflams.stream().collect(Collectors.toMap(f -gt; f, SomeClass::validateFlimflam));