Reputation: 625
Java 11 here. I have the following 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;
}
I have a method that validates a Flimflam
and returns a List<String>
of any errors encountered while validating the Flimflam
. I can change this to return Optional<List<String>>
if anyone thinks thats helpful for some reason, especially when dealing with the Stream API:
public List<String> validateFlimflam(Flimflam flimflam) {
List<String> errors = new ArrayList<>();
// ... validation code omitted for brevity
// 'errors' list is populated with any errors; otherwise it returns empty
return errors;
}
I want to stream (Stream API) through a List<Flimflam>
and populate a Map<Flimflam,List<String>>
errors map, where the key of the map is a Flimflam
that failed validation, and its corresponding value is the list of validation error strings.
I can achieve this the "old fashioned" way like so:
List<Flimflam> flimflams = getSomehow();
Map<Flimflam,List<String>> errorsMap = new HashMap<>();
for (Flimflam ff : flimflams) {
List<String> errors = validateFlimflam(ff);
if (!errors.isEmpty() {
errorsMap.put(ff, errors);
}
}
How can I accomplish this via the Stream API?
Upvotes: 0
Views: 124
Reputation: 40047
It is hard to tell where exactly your validateFlimflam
method is defined. I suspect it is not in the Flimflam
class itself since there would be no need to pass an instance of itself to the method. So I presume it is an external method to that class. Assuming that I would proceed as follows:
thisClass = instance containing validateFlimflam
. Could be set to this
Map<Flimflam, List<String>> errorsMap =
flimflams.stream().collect(Collectors.toMap(f -> f,
thisClass::validateFlimflam));
If by chance, Flimflam
does contain validateFlimflam
you could do it like this. Note that this presumes the method takes no arguments as they wouldn't be necessary
Map<Flimflam, List<String>> errorsMap =
flimflams.stream().collect(Collectors.toMap(f -> f,
Flimflam::validateFlimflam));
Finally, if the containing class is some other class and the validateFlimflam
method is declared static, then you could do it like this by using the containing class name, not instance. Also, in this case, the method would take an argument as defined.
Map<Flimflam, List<String>> errorsMap =
flimflams.stream().collect(Collectors.toMap(f -> f,
SomeClass::validateFlimflam));
Upvotes: 0
Reputation: 2385
Like this
Map<Flimflam,List<String>> errorsMap = flimflams.stream().collect(Collectors.toMap(f -> f, f-> f::validateFlimflam));
toMap
takes 2 parameters (keyMapper,valueMapper)
In your case key mapper is object from stream itself, and value is calling validateFlimflam on that object
Upvotes: 1