Zir*_*ael 5 java lambda java-8 java-stream collectors
无法弄清楚如何读取特定建筑物列表中动物的平均体重。
我编写了另一种获取每种动物的动物名称的方法,所以我知道我的持久性正在起作用。
动物园:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
动物:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
建造:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我想获取每个建筑物中动物的平均体重,所以我的想法是传递建筑物的名称。每个建筑物对象都存储一列动物,我需要建筑物对象,因为它存储建筑物的名称,但是我不知道如何使用流访问它。我知道在我发布的代码中,我实际上还没有使用buildingName,但这是因为我什至无法正常获得动物的平均体重。重量存储为动物中的两倍,并且我的持久性正在发挥作用,因为我已经通过其他方式对此进行了测试。凡是具有流技术经验的人都可以解释如何通过构建进行过滤并获得该平均权重。
如果您有使用Java9的自由,我建议您使用flatMapping收集器来完成此工作。这是它的外观。
Map<String, Double> avgWeightByBuildingName = buildings.stream()
.collect(Collectors.groupingBy(Building::getName,
Collectors.flatMapping(b -> b.getAnimals().stream(),
Collectors.averagingDouble(Animal::getWeight))));
Run Code Online (Sandbox Code Playgroud)
但是,这是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)));
Run Code Online (Sandbox Code Playgroud)
或者,考虑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]));
}
Run Code Online (Sandbox Code Playgroud)
此外,对于以下较新的Java版本,这具有简单的迁移策略,如下面的注释所述。
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |