【发布时间】:2020-11-19 18:21:40
【问题描述】:
给定,
class Foo {
private Long id;
private String name;
private String category;
private List<String> categories;
// getters & setters
}
我有一个对象列表。
final Foo f1 = new Foo(1L, "a", "c1");
final Foo f2 = new Foo(1L, "a", "c2");
final Foo f3 = new Foo(2L, "a", "c1");
final List<Foo> li = List.of(f1, f2, f3);
看起来像
{[Foo [id=1, name=a, category=c1, categories=null], Foo [id=1, name=a, category=c2, categories=null]], [Foo [id=2, name=a, category=c1, categories=null]]}
我想把它改成
[Foo [id=1, name=a, category=null, categories=[c1, c2]], Foo [id=2, name=a, category=null, categories=[c1]]]
即将个人category 整理到 categories 列表中。
这是实现我想要的当前代码。
public static void main(final String[] args) {
final Foo f1 = new Foo(1L, "a", "c1");
final Foo f2 = new Foo(1L, "a", "c2");
final Foo f3 = new Foo(2L, "a", "c1");
final List<Foo> li = List.of(f1, f2, f3);
li.forEach(e -> System.out.println(e));
final Map<Long, List<Foo>> collect = li.stream().collect(Collectors.groupingBy(Foo::getId));
System.out.println(collect);
final List<Foo> grouped = new ArrayList<>();
collect.forEach((k, v) -> {
System.out
.println("key=" + k + "val=" + v.stream().map(e1 -> e1.getCategory()).collect(Collectors.toList()));
final Foo foo = collect.get(k).get(0);
foo.setCategories(v.stream().map(e1 -> e1.getCategory()).collect(Collectors.toList()));
foo.setCategory(null);
grouped.add(foo);
});
System.out.println(grouped);
}
有没有什么方法可以单独使用流和 lambda,而不必分成多个步骤?目标是让这段代码更优雅、更易读,并向读者传达意图。
这个问题本质上与Group by and sum objects like in SQL with Java lambdas? 相似,但对我没有帮助,因为这里已经完成了聚合,而这里不是聚合。
【问题讨论】:
-
严格按照流和 lambda 重新表达计算通常是可能的,但在许多情况下,结果不太优雅、难以阅读且难以理解。想出这样的转变越难,你就越有可能朝着与既定目标相反的方向前进。
-
仅供参考,当您希望改进工作代码时,codereview.stackexchange.com 更合适。
-
@jaco0646 一个我不知道存在的全新世界(或者不知道是专门建造的)!谢谢!
标签: java java-stream