[英]Java Stream Generate Map from List of Objects
I have a class like this.我有一堂这样的课。
public class Foo {
private String prefix;
private String sector;
private int count;
}
Given a foo list:给定一个 foo 列表:
//Args: prefix, sector, count
fooList.add(new Foo("44",,"RowC", 1 ));
fooList.add(new Foo("1",,"Rowa", 1 ));
fooList.add(new Foo("1",,"RowB", 1 ));
fooList.add(new Foo("1",,"Rowa", 1 ));
And I need to return the request an object sorted by Prefix asc like this:我需要返回一个按 Prefix asc 排序的对象的请求,如下所示:
{
"1": {
"Rowa": "2",
"RowB": "1"
},
"44": {
"RowC": "1"
}
}
So the problem is: I have to group the list by the prefix, and then show, every sector and the count(*) of items on the list with the same row and sector.所以问题是:我必须按前缀对列表进行分组,然后显示每个扇区和列表中具有相同行和扇区的项目的计数(*)。 The far that I got is using stream like this:我得到的远是使用这样的流:
fooList.stream()
.collect(Collectors.groupingBy(
Foo::getPrefix,
Collectors.groupingBy(
Foo::getSector,
Collectors.mapping(Foo::getSector , Collectors.counting())
)
));
The problem is, that the code above, is that the count is a Long, and I need to return as a String.问题是,上面的代码是计数是一个长整数,我需要作为一个字符串返回。 I've tried with .toString but it gives me an error (Can assign java.lang.String to java.util.stream.Collector).我试过 .toString 但它给了我一个错误(可以将 java.lang.String 分配给 java.util.stream.Collector)。
UPDATE更新
With the help of Andreas and Naman, now I can map count as String.在 Andreas 和 Naman 的帮助下,现在我可以将 count 映射为 String。 I just need it sorted by Prefix.我只需要按前缀排序。
Can anyone help me?谁能帮我?
You were almost there, just replace the Collectors.mapping
line with:你快到了,只需将Collectors.mapping
行替换为:
Collectors.summingInt(Foo::getCount))
As in:如:
List<Foo> fooList = new ArrayList<>();
fooList.add(new Foo("44", "RowC", 1 ));
fooList.add(new Foo("1", "Rowa", 1 ));
fooList.add(new Foo("1", "RowB", 1 ));
fooList.add(new Foo("1", "Rowa", 1 ));
Map<String, Map<String, String>> result = fooList.stream().collect(
Collectors.groupingBy(
Foo::getPrefix,
TreeMap::new, // remove if prefix sorting not needed
Collectors.groupingBy(
Foo::getSector,
() -> new TreeMap<>(Collator.getInstance()), // remove if sector sorting not needed
Collectors.collectingAndThen(
Collectors.summingInt(Foo::getCount),
String::valueOf
)
)
)
);
System.out.println(result); // prints: {1={Rowa=2, RowB=1}, 44={RowC=1}}
Notice the TreeMap
constructors added to the groupingBy()
calls, which ensures that the maps are sorted.请注意添加到groupingBy()
调用中的TreeMap
构造函数,它确保对映射进行排序。 The first is sorting lexicographically , while the second sorts according to spoken language, ie upper- vs lowercase doesn't affect order.第一个是按字典顺序排序,而第二个根据口语排序,即大写与小写不影响顺序。
Is this what you need?这是你需要的吗?
Code :代码 :
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;
public class Main {
public static void main(String [] args){
List<Foo> fooList = new ArrayList<>();
fooList.add(new Foo("44", "RowC", 1 ));
fooList.add(new Foo("1", "Rowa", 1 ));
fooList.add(new Foo("1", "RowB", 1 ));
fooList.add(new Foo("1", "Rowa", 1 ));
Map<String, Map<String, Integer>> result = grouper(fooList);
result.forEach( (k,v) -> System.out.printf("%s\n%s\n", k,v) );
}
/* group the list by the prefix, and then show, every sector and the
* count(*) of items on the list with the same row and sector.*/
public static Map<String, Map<String, Integer>> grouper(List<Foo> foos){
//Map<prefix, Map<sector, count>
Map<String, Map<String, Integer>> result = foos.stream()
.collect(
//Step 1 - group by prefix. Outer map key is prefix.
groupingBy( Foo::getPrefix,
//Use a tree map which wil be sorted by its key, i.e prefix.
TreeMap::new,
//Step 2 - group by sector.
groupingBy( Foo::getSector,
//Step 3 - Sum the Foo's in each sector in each prefix.
summingInt(Foo::getCount)
)
)
);
return result;
}
}
Output :输出 :
1
{Rowa=2, RowB=1}
44
{RowC=1}
PS - I referred to this tutorial to answer your question. PS - 我参考本教程来回答您的问题。 I referred to the examples in " 2.5. Grouping by Multiple Fields " and " 2.7. Getting the Sum from Grouped Results ".我参考了“ 2.5. 按多个字段分组”和“ 2.7. 从分组结果中获取总和”中的示例。 The next step was to find out how to also order by the key of a map while grouping which I got from " 2.11. Modifying the Return Map Type " and also checked it here .下一步是找出如何在分组时按地图键进行排序,这是我从“ 2.11. 修改返回地图类型”中获得的,并在此处进行了检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.