给出以下示例类:
class Foo{
String name;
int value;
public Foo(String name, int value) {
this.name = name;
this.value = value;
}
// getters, setters, toString & equals
}
Run Code Online (Sandbox Code Playgroud)
和 foo 列表:
List<Foo> fooList = List.of(new Foo("A",1), new Foo("A",2),
new Foo("B",1),
new Foo("C",1),
new Foo("D",1), new Foo("D",2), new Foo("D",3)
);
Run Code Online (Sandbox Code Playgroud)
我想获得一份按名称区分的 foo 列表,如果有多个,Foos我想保留具有最高值的那个。
我发现这个java-8-distinct-by-property问题可以按名称获取不同列表的元素,它使用此方法来获取不同的元素:
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
Run Code Online (Sandbox Code Playgroud)
我这样使用它:
fooList.stream().filter(distinctByKey(Foo::getName)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
它可以获取不同的元素,但如果有两个或多个同名元素,则保留列表中的第一个元素,并且我无法添加条件来保留具有最高值的元素。
另一种选择是使用分组依据:
Map<String,List<Foo>> map = fooList.stream().collect(Collectors.groupingBy(f -> f.getName()));
Run Code Online (Sandbox Code Playgroud)
这里我不知道如何从地图中收集具有最高值的Foos到列表中。
使用第一种方法我得到:
Foo{name=A, value=1}
Foo{name=B, value=1}
Foo{name=C, value=1}
Foo{name=D, value=1}
Run Code Online (Sandbox Code Playgroud)
与第二个:
A=[Foo{name=A, value=1}, Foo{name=A, value=2}]
B=[Foo{name=B, value=1}]
C=[Foo{name=C, value=1}]
D=[Foo{name=D, value=1}, Foo{name=D, value=2}, Foo{name=D, value=3}]
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得以下列表:
Foo{name=A, value=2}
Foo{name=B, value=1}
Foo{name=C, value=1}
Foo{name=D, value=3}
Run Code Online (Sandbox Code Playgroud)
您可以使用groupBy(classifier,下游)方法。
分类函数将元素映射到某个关键类型 K。下游收集器对类型 T 的元素进行操作并生成类型 D 的结果。生成的收集器生成一个 Map。
片段
fooList.stream().collect(
Collectors.groupingBy(Foo::getName,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparing(Foo::getValue)),
Optional::get
)
)
).values().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
输出
Foo{name='A', value=2}
Foo{name='B', value=1}
Foo{name='C', value=1}
Foo{name='D', value=3}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1887 次 |
| 最近记录: |