我有以下实体:
ID | PROPERTY
FOO | A
FOO | Z
JOHN | A
DOE | Z现在,我想按ID对这些实体进行分组,如果存在一个或两个值,则获取属性为'A‘的实体,否则为Z。
因此,输出应为:
FOO | A
JOHN | A
DOE | Z我在考虑groupingBy流方法,但我不知道如何使用什么收集器,如果也不是正确的解决方案:
list.stream()
.collect(Collectors.groupingBy(o -> o.getId(), ? another collector function ?)
.collect(Collectors.toList()));发布于 2020-10-09 19:07:44
试试这个:
entities.stream()
.collect(toMap(YourEntityType::getId,
YourEntityType::getProperty,
(x, y) -> "A".equals(x) ? x : y));更新:
我刚刚注意到@Holger在他的评论中发布了完全相同的东西,而我正在编辑我的答案。不过,这里有两个小区别:
"A".equals(x)更不容易出错,比更安全。如果x为null.,则NPE将导致后者失败
更新2:
既然您想要列表形式的结果,那么此选项应该适用于您:
entities.stream()
.collect(collectingAndThen(
toMap(YourEntityType::getId,
identity(),
(x, y) -> "A".equals(x.getProperty()) ? x : y,
m -> new ArrayList<YourEntityType>(m.values()));发布于 2020-10-09 20:25:05
如果您坚持使用分组收集器,则? another collector function ?将如下所示:
public static void main(String[] args) {
record C(String id, String property) {}
List<C> list = List.of(new C("FOO","A"),new C("FOO","Z"),new C("JOHN","A"),new C("DOE","Z"),new C("XXX","X"));
System.out.println(list);
Object result = list.stream()
.collect(Collectors.groupingBy(o -> o.id, Collectors.collectingAndThen(Collectors.reducing((l,r) -> "A".equals(l.property) ? l : r), Optional::get)));
System.out.println(result);
},这一想法建议纠正几乎@ETO的解决方案。
(抱歉,我有记录,我懒得使用getter。)
发布于 2020-10-10 21:59:35
// Utility class with methods you can reuse for other purposes too
public final class StreamUtil {
private StreamUtil() {}
public static <T, U> Predicate<T> distinctBy(Function<T, U> keyFunction) {
final Set<U> uniqueKeys = synchronizedSet(new HashSet<>());
return item -> uniqueKeys.add(keyFunction.apply(item));
}
}和您的问题的解决方案
entities.stream()
.sorting(Comparator.comparing(Entity::getProperty)) // order entities according to priorities
.filter(StreamUtil.distinctBy(Entity::getId)) // take first entity only per key
... // here you have stream as per you requirements. You can collect() it or continue mapping/filtering由于排序的原因,此解决方案比此处建议的其他解决方案要慢。然而,它有它的优势-更容易阅读,而速度慢只会在大型集合上发挥作用。
https://stackoverflow.com/questions/64278525
复制相似问题