收集器按特征和所述特征字段的最小值进行分组

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

标题有点令人困惑,但我不确定如何用简单的句子解释我的问题。

我有一个家庭作业任务,使用流和收集器按长度(在本例中与周长相同)对矩形数组列表进行分组,并计算每个组的最小宽度。我尝试过以下方法:

public static Map<Double, Double> groupIndenticalPerimeterWidth(ArrayList<Rectangle> rectangles){
        return rectangles.stream().collect(Collectors.groupingBy(Rectangle::getLength, Collectors.minBy((rectangle1, rectangle2) -> Double.compare(rectangle1.getWidth(), rectangle2.getWidth()))));
    }

这给了我一个

Map<Double, Optional<Rectangle>>
,我不知道如何在
Collectors.groupingBy
的第二个参数而不是
Optional<Rectangle>

中获取最小矩形的宽度

任何帮助表示赞赏

java java-stream collectors
2个回答
2
投票

使用流和收集器按

length
(在本例中与周长相同)对矩形数组列表进行分组,并计算每个组的最小值
width

正如您所注意到的,collector

minBy()
产生
Optional<Rectangle>

要从可选结果中获取双重属性,您可以使用collector

collectingAndThen()
。它期望一个收集器(在本例中为
minBy()
)作为第一个参数,以及一个将 collector 生成的结果转换为第二个参数的 function

public static Map<Double, Double> groupIndenticalPerimeterWidth(ArrayList<Rectangle> rectangles){
    return rectangles.stream()
        .collect(Collectors.groupingBy(
            Rectangle::getPerimeter,
            Collectors.collectingAndThen(
                Collectors.minBy(Comparator.comparingDouble(Rectangle::getWidth)),
                result -> result.map(Rectangle::getWidth).orElseThrow() // `map` transforms Optional<Rectangle> into Optional<Double> and `orElseThrow` extracts the value from the optional
            )
        ));
}

虚拟

Rectangle
类:

public static class Rectangle {
    private double height;
    private double width;
    
    public double getPerimeter() {
        return 2 * (height + width);
    }

    // getters
}

旁注:当您需要定义压缩器时,强烈建议使用 Java 8 静态方法。


0
投票

不需要提取可选的

groupingBy
,您可以使用具有合并功能的
toMap
来更轻松地做到这一点:

 public static Map<Double, Double> groupIndenticalPerimeterWidth(List<Rectangle> rectangles) {
    return rectangles.stream()
                     .collect(Collectors.toMap(
                           Rectangle::getPerimeter, Rectangle::getWidth, Math::min));
}
© www.soinside.com 2019 - 2024. All rights reserved.