Home > database >  Mapping fields of List to fields of a single Object
Mapping fields of List to fields of a single Object

Time:06-28

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.

  • Related