Java Streams –如何按值分组并找到每个组的最小值和最大值?

编程入门 行业动态 更新时间:2024-10-12 01:26:10
本文介绍了Java Streams –如何按值分组并找到每个组的最小值和最大值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

以我的示例为例,拥有汽车对象,并根据模型(分组依据)发现了最小和最大价格值.

For my example, having car object and found that min and max price value based on model (group by).

List<Car> carsDetails = UserDB.getCarsDetails(); Map<String, DoubleSummaryStatistics> collect4 = carsDetails.stream() .collect(Collectors.groupingBy(Car::getMake, Collectors.summarizingDouble(Car::getPrice))); collect4.entrySet().forEach(e->System.out.println(e.getKey()+" "+e.getValue().getMax()+" "+e.getValue().getMin())); output : Lexus 94837.79 17569.59 Subaru 96583.25 8498.41 Chevrolet 99892.59 6861.85

但是我找不到哪个汽车对象具有最高和最低价格.我该怎么办?

But I couldn't find which car objects have max and min price. How can I do that?

推荐答案

如果每个组仅对一个Car感兴趣,则可以使用例如

If you were interested in only one Car per group, you could use, e.g.

Map<String, Car> mostExpensives = carsDetails.stream() .collect(Collectors.toMap(Car::getMake, Function.identity(), BinaryOperator.maxBy(Comparatorparing(Car::getPrice)))); mostExpensives.forEach((make,car) -> System.out.println(make+" "+car));

但是,由于您想要最昂贵和最便宜的产品,因此需要这样的东西:

But since you want the most expensive and the cheapest, you need something like this:

Map<String, List<Car>> mostExpensivesAndCheapest = carsDetails.stream() .collect(Collectors.toMap(Car::getMake, car -> Arrays.asList(car, car), (l1,l2) -> Arrays.asList( (l1.get(0).getPrice()>l2.get(0).getPrice()? l2: l1).get(0), (l1.get(1).getPrice()<l2.get(1).getPrice()? l2: l1).get(1)))); mostExpensivesAndCheapest.forEach((make,cars) -> System.out.println(make +" cheapest: "+cars.get(0)+" most expensive: "+cars.get(1)));

由于没有与DoubleSummaryStatistics等效的通用统计对象,因此该解决方案带来了一些不便.如果这种情况不止一次发生,那么值得用这样的课程填补这一空白:

This solution bears a bit of inconvenience due to the fact that there is no generic statistics object equivalent to DoubleSummaryStatistics. If this happens more than once, it’s worth filling the gap with a class like this:

/** * Like {@code DoubleSummaryStatistics}, {@code IntSummaryStatistics}, and * {@code LongSummaryStatistics}, but for an arbitrary type {@code T}. */ public class SummaryStatistics<T> implements Consumer<T> { /** * Collect to a {@code SummaryStatistics} for natural order. */ public static <T extends Comparable<? super T>> Collector<T,?,SummaryStatistics<T>> statistics() { return statistics(Comparator.<T>naturalOrder()); } /** * Collect to a {@code SummaryStatistics} using the specified comparator. */ public static <T> Collector<T,?,SummaryStatistics<T>> statistics(Comparator<T> comparator) { Objects.requireNonNull(comparator); return Collector.of(() -> new SummaryStatistics<>(comparator), SummaryStatistics::accept, SummaryStatistics::merge); } private final Comparator<T> c; private T min, max; private long count; public SummaryStatistics(Comparator<T> comparator) { c = Objects.requireNonNull(comparator); } public void accept(T t) { if(count == 0) { count = 1; min = t; max = t; } else { if(cpare(min, t) > 0) min = t; if(cpare(max, t) < 0) max = t; count++; } } public SummaryStatistics<T> merge(SummaryStatistics<T> s) { if(s.count > 0) { if(count == 0) { count = s.count; min = s.min; max = s.max; } else { if(cpare(min, s.min) > 0) min = s.min; if(cpare(max, s.max) < 0) max = s.max; count += s.count; } } return this; } public long getCount() { return count; } public T getMin() { return min; } public T getMax() { return max; } @Override public String toString() { return count == 0? "empty": (count+" elements between "+min+" and "+max); } }

将其添加到您的代码库后,您可以像使用它

After adding this to your code base, you may use it like

Map<String, SummaryStatistics<Car>> mostExpensives = carsDetails.stream() .collect(Collectors.groupingBy(Car::getMake, SummaryStatistics.statistics(Comparatorparing(Car::getPrice)))); mostExpensives.forEach((make,cars) -> System.out.println(make+": "+cars));

如果getPrice返回double,则使用ComparatorparingDouble(Car::getPrice)代替Comparatorparing(Car::getPrice)可能更有效.

If getPrice returns double, it may be more efficient to use ComparatorparingDouble(Car::getPrice) instead of Comparatorparing(Car::getPrice).

更多推荐

Java Streams –如何按值分组并找到每个组的最小值和最大值?

本文发布于:2023-10-28 01:26:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1535090.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:最大值   最小值   Java   Streams

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!