Suppose, I have a List of cats like this:
[Cat[name="Minnie", age=3], Cat[name="Pixie", age=1], Cat[name="Kazy", age=5]]
And an Object Cats with fields:
class Cats {
int MinnieAge;
int PixieAge;
int KazyAge;
}
What is the best way to map the ages to this Object? Preferably avoiding imperative approach and keeping it nice and clean. Is this possible with MapStruct or the streams API?
CodePudding user response:
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);
}
CodePudding user response:
Hello this is most simple way in my opinion.
1 - class for cat
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
2 - class for animals
public class Animals {
public List<Cat> cats;
public Animals(List<Cat> cats){
this.cats = cats;
}
3 - any class what run method
private void run(){
new Animals(List.of(
new Cat("Minnie",5),
new Cat("Pixie",2),
new Cat("Kazy",3)
));
}
Then you can do whatever you want.