我有一个类似的课程:
public class Product{
public Integer category;
public Integer price;
// getters and setters omitted
}
有了不同类别和价格的产品清单,我想返回一个包含每个类别最便宜产品的清单。我已经找到了一种方法来将此作为一个以类别为键的地图,但我想要一个列表。什么是简洁易读的方法呢?
这是我到目前为止给我的地图:
Map<String, Product> cheapestProducts = products.stream()
.collect(
groupingBy(
Product::getCategory,
collectingAndThen(minBy(comparing(Product::getPrice)), p -> p.get())
)
);
答案 0 :(得分:2)
您可以使用toMap方法,然后调用map.values():
Collection<Product> cheapestProducts = products
.stream()
.collect(Collectors.toMap(t -> t.category, u -> u,
(a, b) -> a.price > b.price ? b : a))
.values();
如果您真的想要一份清单,请参阅上面的Holger评论。
答案 1 :(得分:1)
在我看来,你的方法还可以。问题在于可读性,我认为解决方案是在需要时提取方法使其可重复使用。 Java 8流是流畅的,等等,但通常有诱惑,使流20行,这会损害可读性。因此,通过提取方法getMinBy()
(可能有一个更好的名称),它封装了minBy
和Optional::get
,我认为它更具可读性。当然,该方法本身并不简洁,但可以重复使用。
Map<Integer, Product> cheapestProducts = products.stream()
.collect(
groupingBy(
Product::getCategory,
getMinBy(Product::getPrice)
));
private static <T,C extends Comparable<? super C>> Collector<T, ?, T> getMinBy(Function<T, C> comparatorFunction) {
return collectingAndThen(minBy(comparing(comparatorFunction)), Optional::get);
}
答案 2 :(得分:0)
要从Map获取值到列表,您可以执行以下操作...
List<Value> list = new ArrayList<Value>(map.values());