如何解决Java 11 Lambda,通过相同的属性和具有一定条件的过滤器进行聚合 更新:更新2:
我有以下实体:
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()));
解决方法
尝试一下:
entities.stream()
.collect(toMap(YourEntityType::getId,YourEntityType::getProperty,(x,y) -> "A".equals(x) ? x : y));
更新:
我刚刚注意到@Holger在编辑答案时在他的评论中发布了完全相同的内容。但是有两个小的区别:
- 我更喜欢使用方法引用而不是lambda(这是一个问题,但是我发现它们比lambdas容易出错)
-
"A".equals(x)
比x.equals("A")
安全。如果x
为null
,则后者将因NPE而失败。
更新2:
由于您希望结果以列表形式出现,因此此选项应该对您有效:
entities.stream()
.collect(collectingAndThen(
toMap(YourEntityType::getId,identity(),y) -> "A".equals(x.getProperty()) ? x : y,m -> new ArrayList<YourEntityType>(m.values()));
,
如果您坚持使用分组收集器,则? 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",new C("DOE",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);
}
,Idea建议将其更正为@ETO的解决方案。
(道歉,有记录,我懒于使用吸气剂。)
,// 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
由于排序,此解决方案比此处建议的其他解决方案要慢。 但是,它有其优势-易于阅读,而缓慢只会在大型收藏中出现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。