将List的字段映射到单个Object的字段

问题描述 投票:0回答:3

假设,我有一个这样的猫列表:

[Cat[name="Minnie", age=3], Cat[name="Pixie", age=1], Cat[name="Kazy", age=5]]

还有一个带有字段的对象猫:

class Cats {
int MinnieAge;
int PixieAge;
int KazyAge;
}

将年龄映射到该对象的最佳方法是什么?最好避免命令式方法并保持良好和干净。这可以通过 MapStruct 或 Streams API 实现吗?

java spring stream mapping mapstruct
3个回答
0
投票

如果您想使用流,您可以从实现收集器开始:

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. - 这里的组合器更像是一个存根,因为没有提供组合逻辑的要求。

P.P.S - 还有一些假设可以简化访问修饰符的内容。

那么如果你有这样的模型:

public class Cats {
    int minnieAge;
    int pixieAge;
    int kazyAge;

    @Override
    public String toString() {
        return "Cats{" +
                "minnieAge=" + minnieAge +
                ", pixieAge=" + pixieAge +
                ", kazyAge=" + kazyAge +
                '}';
    }
}

您可以使用自定义收集器:

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);
}

0
投票

这是一个纯 Java 解决方案,它使用 Stream API 创建从猫名到年龄的映射。 然后通过按键单独设置

Cats
对象的各个字段。

Map<String, Integer> agesByName =
        cats.stream().collect(Collectors.toMap(Cat::getName, Cat::getAge));

Cats result = new Cats();
result.MinnieAge = agesByName.get("Minnie");
result.PixieAge = agesByName.get("Pixie");
result.KazyAge = agesByName.get("Kazy");

-2
投票

我将定义一个具有属性名称和年龄的 Cat 类。 然后简单地将输入字符串解析为 cat 对象并将它们存储在已经支持流的列表中。 请参阅下面的示例:

import java.util.*;
class Cat {
    public String name;
    public int age;
    private Cat(String name, int age) { this.name = name; this.age = age;}
    public String toString(){
        return String.format("Cat[name=\"%s\", age=%d]",name,age);
    }
    public static List<Cat> parse(String input) {
        List cats = new ArrayList();
        int i = 0;
        while (true) {
            i = input.indexOf("name=", i);
            if (i < 0) break;
            String name = input.substring(i + 6, input.indexOf("\"", i + 7));
            i = input.indexOf("age=", i);
            int age = Integer.parseInt(input.substring(i + 4, input.indexOf("]", i)));
            cats.add(new Cat(name, age));
        }
        return cats;
    }
}
public class Main{
    public static void main(String[] args) {
        String input = "[Cat[name=\"Minnie\", age=3], Cat[name=\"Pixie\", age=1], Cat[name=\"Kazy\", age=5]]";
        List<Cat> cats = Cat.parse(input);
        cats.forEach(System.out::println);
        cats.stream().filter(e->e.age > 4).forEach(System.out::println);
    }
}

输出:

run:
Cat[name="Minnie", age=3]
Cat[name="Pixie", age=1]
Cat[name="Kazy", age=5]
Cat[name="Kazy", age=5]
BUILD SUCCESSFUL (total time: 0 seconds)
© www.soinside.com 2019 - 2024. All rights reserved.