在流操作中,如何将一组值映射到另一个值?

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>。在此之后,您无法访问洞穴人对象的属性,因为您已将流转换为不同的类型。所以你要做的是:

  1. year.
  2. 对流进行分组
  3. 在每一年内,根据 gender 进行额外分组。
  4. 现在将函数应用于您的列表。

注意:假设 Collectors.groupingByCollectors.counting() 的静态导入:

Function<Stream<CavePerson>, Map<Integer, Map<String, Long>>> mapper
    = str -> str.collect(groupingBy(c -> c.year, 
                                    groupingBy(c -> c.gender, counting())));