假设,我有一个这样的猫列表:
[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 实现吗?
如果您想使用流,您可以从实现收集器开始:
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);
}
这是一个纯 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");
我将定义一个具有属性名称和年龄的 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)