Home > database >  How do I create a BiFunction stream based off of categories?
How do I create a BiFunction stream based off of categories?

Time:05-01

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...
  • Related