If you want to use streams you can start from implementing a collector:
public class CatsCollector implements Collector<Cat, Cats, Cats> {
@Override
public Supplier<Cats> supplier() {
return () -> new Cats();
}
@Override
public BiConsumer<Cats, Cat> accumulator() {
return (cats1, cat) -> {
switch (cat.name){
case "Minnie": cats1.minnieAge = cat.age; break;
case "Pixie": cats1.pixieAge = cat.age; break;
case "Kazy": cats1.kazyAge = cat.age; break;
}
};
}
@Override
public BinaryOperator<Cats> combiner() {
return (cats1, cats2) -> cats1;
}
@Override
public Function<Cats, Cats> finisher() {
return cats1 -> cats1;
}
@Override
public Set<Characteristics> characteristics() {
return Set.of(Characteristics.UNORDERED);
}
}
P.S. - Here a combiner is more like a stub because there are no requirements for combining logic provided.
P.P.S - There are also sort of assumptions to simplify access modifiers stuff.
Then if you have the model like this:
public class Cats {
int minnieAge;
int pixieAge;
int kazyAge;
@Override
public String toString() {
return "Cats{" +
"minnieAge=" + minnieAge +
", pixieAge=" + pixieAge +
", kazyAge=" + kazyAge +
'}';
}
}
You can use your custom collector:
public static void main(String[] args) {
List<Cat> cats = List.of(
new Cat("Minnie", 3),
new Cat("Pixie", 1),
new Cat("Kazy", 5));
Cats catsResult = cats.stream().collect(new CatsCollector());
System.out.println(catsResult);
}