在流操作中,如何将一组值映射到另一个值?
From a stream operation, how do I map a set of values to anoter value?
这是一个名为 CavePerson
的修改过的人 class。它没有吸气剂,但确实有对应于 CSV/Excel 文件中索引的变量。每个 CavePerson
都有编号、姓名、性别和介绍他们的年份。
public class CavePerson {
public final int num;
public final String name;
public final String gender;
public final int intro_year;
public CavePerson (int aNum, String aName, String aGender, int anIntro_year){
this.num = aNum;
this.name = aName;
this.gender = aGender;
this.intro_year = anIntro_year;
}
public static CavePerson lineValues(String line) {
String array = line.split(",");
int numA = array[0];
String nameA = array[1];
String genderA array[2];
int intro_yearA = array[3];
return new CavePerson(numA, nameA, genderA, intro_yearA);
}
}
此 cavepeople.csv
文件中的每一行都是一个 CavePerson
对象:
Num
Name
Gender
Year
1
Fred
Male
1960
2
Wilma
Female
1960
3
Barney
Male
1961
4
Betty
Female
1961
5
Dino
Male
1964
6
BamBam
Male
1966
7
Puss
Male
1967
8
Pebbles
Female
1966
我正在练习流,我想统计每年引入的每个性别。预期结果 return 每年的地图并列出当年引入的 male/female 字符数。它应该是这样的:
1960, Male 1, Female 1
这就是我目前所拥有的。从 Stream
,我将每年映射到每个性别字符的计数,但我收到类型错误,指出我无法将 Map<Object,Long>
转换为我想要的 Map<Integer, Map<String,Long>>
Function<Stream<CavePerson>, Map<Integer, Map<String, Long>>> getGenderByYear =
e -> e.map(x -> x.year)
.collect(Collectors.groupingBy((CavePerson-> CavePerson.gender), Collectors.counting()));
我是不是漏掉了什么?
您的函数将输入作为 Stream<CavePerson>
。因此,一旦执行 e.map(x -> x.year)
,Stream 就会转换为 Stream<Integer>
。在此之后,您无法访问洞穴人对象的属性,因为您已将流转换为不同的类型。所以你要做的是:
- 按
year
. 对流进行分组
- 在每一年内,根据
gender
进行额外分组。
- 现在将函数应用于您的列表。
注意:假设 Collectors.groupingBy
和 Collectors.counting()
的静态导入:
Function<Stream<CavePerson>, Map<Integer, Map<String, Long>>> mapper
= str -> str.collect(groupingBy(c -> c.year,
groupingBy(c -> c.gender, counting())));
这是一个名为 CavePerson
的修改过的人 class。它没有吸气剂,但确实有对应于 CSV/Excel 文件中索引的变量。每个 CavePerson
都有编号、姓名、性别和介绍他们的年份。
public class CavePerson {
public final int num;
public final String name;
public final String gender;
public final int intro_year;
public CavePerson (int aNum, String aName, String aGender, int anIntro_year){
this.num = aNum;
this.name = aName;
this.gender = aGender;
this.intro_year = anIntro_year;
}
public static CavePerson lineValues(String line) {
String array = line.split(",");
int numA = array[0];
String nameA = array[1];
String genderA array[2];
int intro_yearA = array[3];
return new CavePerson(numA, nameA, genderA, intro_yearA);
}
}
此 cavepeople.csv
文件中的每一行都是一个 CavePerson
对象:
Num | Name | Gender | Year |
---|---|---|---|
1 | Fred | Male | 1960 |
2 | Wilma | Female | 1960 |
3 | Barney | Male | 1961 |
4 | Betty | Female | 1961 |
5 | Dino | Male | 1964 |
6 | BamBam | Male | 1966 |
7 | Puss | Male | 1967 |
8 | Pebbles | Female | 1966 |
我正在练习流,我想统计每年引入的每个性别。预期结果 return 每年的地图并列出当年引入的 male/female 字符数。它应该是这样的:
1960, Male 1, Female 1
这就是我目前所拥有的。从 Stream
,我将每年映射到每个性别字符的计数,但我收到类型错误,指出我无法将 Map<Object,Long>
转换为我想要的 Map<Integer, Map<String,Long>>
Function<Stream<CavePerson>, Map<Integer, Map<String, Long>>> getGenderByYear =
e -> e.map(x -> x.year)
.collect(Collectors.groupingBy((CavePerson-> CavePerson.gender), Collectors.counting()));
我是不是漏掉了什么?
您的函数将输入作为 Stream<CavePerson>
。因此,一旦执行 e.map(x -> x.year)
,Stream 就会转换为 Stream<Integer>
。在此之后,您无法访问洞穴人对象的属性,因为您已将流转换为不同的类型。所以你要做的是:
- 按
year
. 对流进行分组
- 在每一年内,根据
gender
进行额外分组。 - 现在将函数应用于您的列表。
注意:假设 Collectors.groupingBy
和 Collectors.counting()
的静态导入:
Function<Stream<CavePerson>, Map<Integer, Map<String, Long>>> mapper
= str -> str.collect(groupingBy(c -> c.year,
groupingBy(c -> c.gender, counting())));