Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Collectors group by characteristic and minimum value of a field of said characteristic

Title is sort of confusing but I’m not sure how to explain my problem in a simple sentence.

I have a homework task to group an arraylist of rectangles by length (same as perimeter in this case) using streams and collectors and to calculate minimum width for each group. I have tried the following:

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

which gets me a Map<Double, Optional<Rectangle>> and I can’t figure out how to get the width of minimum rectangle in the second arguement of Collectors.groupingBy instead of Optional<Rectangle>

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Any help appreciated

>Solution :

group an arraylist of rectangles by length (same as perimeter in this case) using streams and collectors and to calculate minimum width for each group.

As you’ve noticed, collector minBy() produces Optional<Rectangle>.

To get double property from the optional result, you can use collector collectingAndThen(). It expects a collector (minBy() in this case) as the first argument, and a function that transforms the result produced by the collector as the second argument.

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

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

    public double getHeight() {
        return height;
    }

    public double getWidth() {
        return width;
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading