'From a stream operation, how do I map a set of values to anoter value?
This is a modified Person class named CavePerson. It has no getters, but does have variables that correspond to indexes in a CSV/Excel file. Each CavePerson has a number, name, gender, and the year they were introduced in.
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);
}
}
Each line in this cavepeople.csv file is a CavePerson object:
| 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 |
I am practicing streams, and I wanted to get a count of each gender that was introduced by each year. The expected result return a map of each year and list the number of male/female characters that were introduced that year. It should look like this:
1960, Male 1, Female 1
This is what I have so far. From a Stream, I map each year to the count of each gendered character, but I am getting a type error stating that I cannot convert Map<Object,Long> to my desired 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()));
Am I missing something here?
Solution 1:[1]
Your function takes an input as Stream<CavePerson>. So once you do the e.map(x -> x.year), the Stream is converted to Stream<Integer>. After this you cannot access the properties of the cave person object, because you have converted the stream to a different type. So what you had to do was:
- Group the stream by
year. - Within each year, do an additional grouping based on
gender. - Now apply the function to your list.
Note: assume static imports for Collectors.groupingBy and Collectors.counting():
Function<Stream<CavePerson>, Map<Integer, Map<String, Long>>> mapper
= str -> str.collect(groupingBy(c -> c.year,
groupingBy(c -> c.gender, counting())));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Gautham M |
