Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
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>
Any help appreciated
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() // `map` transforms Optional<Rectangle> into Optional<Double> and `orElseThrow` extracts the value from the optional
Dummy Rectangle
class:
public static class Rectangle {
private double height;
private double width;
public double getPerimeter() {
return 2 * (height + width);
// getters
Sidenote: it's highly advisable to use Java 8 static methods when you need to define a compactor.
Instead of groupingBy
with the necessity to extract an Optional you can do it easier with toMap
with a merge function:
public static Map<Double, Double> groupIndenticalPerimeterWidth(List<Rectangle> rectangles) {
return rectangles.stream()
.collect(Collectors.toMap(
Rectangle::getPerimeter, Rectangle::getWidth, Math::min));
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.