gpt4 book ai didi

java - 使用 Java 流从列表中的列表中平均特定值

转载 作者:搜寻专家 更新时间:2023-10-31 19:51:29 26 4
gpt4 key购买 nike

无法弄清楚如何在特定建筑物的列表中读出动物的平均体重。

我已经编写了另一种方法来获取每种动物的名称,所以我知道我的坚持正在发挥作用。

动物园:

public class Zoo {
private List<Animal> animals;
private List<Building> buildings;

public Zoo() {
this.animals = new PersistencyController().giveAnimals();
this.gebouwen = new PersistencyController().giveBuildings();
}

public List<Animal> giveAnimalsByKind(String kindName) {
return animals.stream().filter(animal -> animal.getKind().getName() == kindName).sorted(Comparator.comparing(Animal::getWeight)).collect(Collectors.toList());
}

public double giveAvgWeightForAnimalsInBuilding(String buildingName) {
return animals.stream().collect(Collectors.averagingDouble(Animal::getWeight));
}
}

动物:

public class Animal implements Serializable {

private int nr;
private String name;
private double weight;
private Kind kind;

public Animal(int nr, String name, double weight, Kind kind) {
this.nr = nr;
this.name = name;
this.weight= weight;
this.kind= kind;
}

public double getWeight() {
return weight;
}

public void setWeight(double weight) {
this.weight = weight;
}
}

建筑:

public class Building{

private String naam;
private int capaciteit;
private final List<Animal> animals = new ArrayList<>();

public Building(String naam, int capaciteit) {
this.naam = naam;
this.capaciteit = capaciteit;
}
}

我想获得每座建筑物的动物的平均重量,所以我的想法是传递建筑物的名称。每个 Building 对象都存储一个动物列表,我需要 building 对象,因为它存储了建筑物的名称,但我不知道如何使用流访问它。我知道在我发布的代码中,我实际上还没有使用 buildingName,但那是因为我什至无法正常获得动物的平均体重。 weight 在 Animal 中存储为 double 并且我的坚持正在发挥作用,因为我已经以其他方式对此进行了测试。非常感谢任何对流有经验的人解释如何通过构建进行过滤并得到这个平均权重。

最佳答案

如果您有使用 Java9 的自由,我建议您使用 flatMapping 收集器来完成这件事。这是它的样子。

Map<String, Double> avgWeightByBuildingName = buildings.stream()
.collect(Collectors.groupingBy(Building::getName,
Collectors.flatMapping(b -> b.getAnimals().stream(),
Collectors.averagingDouble(Animal::getWeight))));

然而,这里的 java8 解决方案与前者相比看起来有点冗长。

Map<String, Double> avgWeightByBuildingName = buildings.stream()
.flatMap(b -> b.getAnimals().stream()
.map(a -> new AbstractMap.SimpleEntry<>(b.getName(), a.getWeight())))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.averagingDouble(Map.Entry::getValue)));

或者考虑按照此 answer 编写自己的 flatMapping 收集器.这是我在查看上述答案和 JDK 9 源代码后想出的一个这样的实现。

static <T, U, A, R> Collector<T, ?, R> flatMapping(Function<? super T,
? extends Stream<? extends U>> mapper, Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
return Collector.of(downstream.supplier(), (r, t) -> {
try (Stream<? extends U> result = mapper.apply(t)) {
result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
}
}, downstream.combiner(), downstream.finisher(),
downstream.characteristics().toArray(new Characteristics[0]));
}

此外,如以下评论所述,它具有针对较新 Java 版本的直接迁移策略。

关于java - 使用 Java 流从列表中的列表中平均特定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57577586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com