This is a continuation from one of my previous questions: If I have a Stream<Class>, how can I access the classes' inherent information such as variables and arrays?
I have a class named CavePerson
with the following structure:
public class CavePerson {
public final int num;
public final String name;
public final String gender;
public final int age;
public CavePerson (int aNum, String aName, String aGender, int anAge){
this.num = aNum;
this.name = aName;
this.gender = aGender;
this.age = anAge;
}
public static CavePerson lineValues(String line) {
String array = line.split(",");
int numA = array[0];
String nameA = array[1];
String genderA array[2];
int ageA = array[3];
return new CavePerson(numA, nameA, genderA, ageA);
}
}
Each line in this cavepeople.csv file is a CavePerson object:
| Num | Name | Gender |Age |
| --- | ---- | ------ | --- |
| 1 | Fred | Male | 41 |
| 2 | Wilma | Female | 36 |
| 3 | Barney | Male | 38 |
| 4 | Betty | Female | 35 |
| 5 | Dino | Pet | 4 |
| 6 | BamBam | Male | 2 |
| 7 | Puss | Pet | 1 |
I am trying to practice using streams on datasets. I want to use a BiFunction that takes a stream of type CavePerson
and a String
.
This String
is one of the defined genders in a CavePerson
object. The stream should return a String[]
, which contains everyone who falls under a specific gender. My expected outcome should look like:
EXPECTED OUTCOME
Given a stream of type `CavePerson` and "Male": [Fred, Barney, BamBam]
Given a stream of type `CavePerson` and "Female": [Wilma, Betty]
Given a stream of type `CavePerson` and "Pet": [Dino, Puss]
This is the beginning of the code, but I am not exactly sure where to go from here:
static BiFunction<Stream<CavePerson>, String, List<String>> getSortedGenders = (e, q) -> List.of(q);
//e.collect(Collectors.groupingBy(CavePerson -> CavePerson.gender), Collectors.toList());
CodePudding user response:
What it looks like is that you just want
stream.collect(
Collectors.groupingBy(
person -> person.gender,
Collectors.mapping(
person -> person.name,
Collectors.toList())));
which does not involve a BiFunction
.
CodePudding user response:
I don't think a BiFunction is what you need, specially not with a stream as one of the params. Note: once a stream has already been operated upon or closed you can not reuse it again. So once you use the BiFunction to get for example the males you can not use that same stream to get the pets or females. Instead you need to read your file again and again to have a stream where you can apply your BiFunction. Nevertheless if you want to do it with a function something like below should work
BiFunction<Stream<CavePerson>, String, String[]> getSortedGenders =
(e, q) -> e.filter(p -> p.gender.equals(q)).map(p -> p.name).toArray(String[]::new);
and use it
Stream<CavePerson> personStream = // read your file and get the stream
String[] males = getSortedGenders.apply(personStream,"Male");
personStream = // read your file again
String[] females = getSortedGenders.apply(personStream,"Female");
I think what you realy want might be a predicate from the discription of your question.
Predicate<CavePerson> isMale = cavePerson -> cavePerson.gender.equals("Male");
Predicate<CavePerson> isPet = cavePerson -> cavePerson.gender.equals("Pet");
which can be used
yourStream.filter(isMale).map(...).collect...