英文:
Unwrap Optional when using Collectors maxBy with groupingBy
问题
以下是翻译好的内容:
我有一个带有`String`和`int`字段的类。
public class Data {
private String name;
private int value;
private Data(String name, int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
}
我有一个`List<Data>`,如果我想创建一个地图(分组),以了解每个*名称*的*最大值*的数据对象,我可以这样做:
Map<String, Optional<Data>> result = list.stream()
.collect(Collectors.groupingBy(Data::getName,
Collectors.maxBy(Comparator.comparing(Data::getValue))));
但是,由于`Collectors.maxBy`的合同,RHS被包装在Optional中,但我想要一个`Map<String, Data>`。
我能想到的一个选项是使用`Collectors.collectingAndThen`,但我将不得不创建一个不必要的中间地图。
list.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Data::getName,
Collectors.maxBy(Comparator.comparing(Data::getValue))),
map -> map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().get()))));
是否有一种使用流来实现这个的成熟方式?
英文:
I have a class with a String
and an int
field.
public class Data {
private String name;
private int value;
private Data(String name, int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
}
I have a List<Data>
and if I want to create a map (grouping) to know the Data object with maximum value for each name, I could do like,
Map<String, Optional<Data>> result = list.stream()
.collect(Collectors.groupingBy(Data::getName,
Collectors.maxBy(Comparator.comparing(Data::getValue))));
But, the RHS is wrapped in an Optional because of the contract of Collectors.maxBy
but I want a Map<String, Data>
.
One option I could think of it to use Collectors.collectingAndThen
, but I will have to create an unnecessary intermediate map.
list.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Data::getName,
Collectors.maxBy(Comparator.comparing(Data::getValue))),
map -> map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().get()))));
Is there an idiomatic way to achieve this using streams?
答案1
得分: 11
你可以使用 BinaryOperator.maxBy
结合 Collectors.toMap
:
Map<String, Data> result = list.stream()
.collect(Collectors.toMap(Data::getName, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Data::getValue))));
英文:
You can use BinaryOperator.maxBy
with Collectors.toMap
Map<String, Data> result = list.stream()
.collect(Collectors.toMap(Data::getName, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Data::getValue))));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论