gpt4 book ai didi

Java 8 stream groupBy pojo

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:01:34 31 4
gpt4 key购买 nike

我有一个 pojo 集合:

public class Foo {
String name;
String date;
int count;
}

我需要遍历集合,按名称和总计数对 Foos 进行分组,然后使用具有总计数的 pojos 创建新集合。

这是我现在的做法:

    List<Foo> foosToSum = ...

Map<String, List<Foo>> foosGroupedByName = foosToSum.stream()
.collect(Collectors.groupingBy(Foo::getName));

List<Foo> groupedFoos = foosGroupedByName.keySet().stream().map(name -> {
int totalCount = 0;
String date = "";
for(Foo foo: foosGroupedByName.get(name)) {
totalCount += foo.getCount();
date = foo.getDate() //last is used
}
return new Foo(name, date, totalCount);
}).collect(Collectors.toList());

有没有更漂亮的方法来使用流?

更新 感谢大家的帮助。所有答案都很棒。我决定在 pojo 中创建合并函数。

最终的解决方案如下:

Collection<Foo> groupedFoos = foosToSum.stream()
.collect(Collectors.toMap(Foo::getName, Function.identity(), Foo::merge))
.values();

最佳答案

您可以使用 groupingBy 来完成或使用 toMap收集器,至于使用哪一个是值得商榷的,所以我会让你决定你喜欢的那个。

为了更好的可读性,我将在 Foo 中创建一个合并函数并在那里隐藏所有合并逻辑。

这也意味着更好的可维护性,因为合并变得越复杂,您只需更改一个地方,那就是 merge方法,而不是流查询。

例如

public Foo merge(Foo another){
this.count += another.getCount();
/* further merging if needed...*/
return this;
}

现在您可以:

Collection<Foo> resultSet = foosToSum.stream()
.collect(Collectors.toMap(Foo::getName,
Function.identity(), Foo::merge)).values();

注意,上面的合并函数改变了源集合中的对象,如果相反,你想保持它不可变,那么你可以构造新的 Foo是这样的:

public Foo merge(Foo another){
return new Foo(this.getName(), null, this.getCount() + another.getCount());
}

此外,如果出于某种原因您明确需要 List<Foo>而不是 Collection<Foo>然后可以使用 ArrayList 来完成复制构造函数。

List<Foo> resultList = new ArrayList<>(resultSet);

更新

正如@Federico 在评论中提到的,上面的最后一个合并函数很昂贵,因为它创建了可以避免的不必要的对象。因此,正如他所建议的那样,一个更友好的替代方法是继续我上面显示的第一个合并函数,然后将您的流查询更改为:

Collection<Foo> resultSet = foosToSum.stream()
.collect(Collectors.toMap(Foo::getName,
f -> new Foo(f.getName(), null, f.getCount()), Foo::merge))
.values();

关于Java 8 stream groupBy pojo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49814096/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com