如何根据类别创建 BiFunction 流?

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

这是我之前的一个问题的延续:

我有一个名为 CavePerson 的 class,其结构如下:

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);
   }
}

此 cavepeople.csv 文件中的每一行都是一个 CavePerson 对象:

| 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   |

我正在尝试练习在数据集上使用流。我想使用一个 BiFunction,它接受一个 CavePerson 类型的流和一个 String.

StringCavePerson 对象中定义的性别之一。信息流应该 return a String[],其中包含属于特定性别的所有人。我的预期结果应该是这样的:

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]

这是代码的开头,但我不确定从这里到哪里去:

static BiFunction<Stream<CavePerson>, String, List<String>> getSortedGenders = (e, q) -> List.of(q);

//e.collect(Collectors.groupingBy(CavePerson -> CavePerson.gender), Collectors.toList());

看起来就是你想要的

stream.collect(
  Collectors.groupingBy(
     person -> person.gender,
     Collectors.mapping(
       person -> person.name,
       Collectors.toList())));

不涉及BiFunction.

我认为 BiFunction 不是您所需要的,特别是不是将流作为参数之一。注意:一旦流已经被操作或关闭,您就不能再次使用它。因此,一旦您使用 BiFunction 获得例如雄性,您就不能使用相同的流来获得宠物或雌性。相反,您需要一次又一次地读取您的文件以获得可以应用您的 BiFunction 的流。不过,如果您想使用类似下面的功能来完成它应该可以工作

BiFunction<Stream<CavePerson>, String, String[]> getSortedGenders =
        (e, q) -> e.filter(p -> p.gender.equals(q)).map(p -> p.name).toArray(String[]::new);

并使用它

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");

我认为您真正想要的可能是您问题描述中的谓词。

Predicate<CavePerson> isMale = cavePerson -> cavePerson.gender.equals("Male");
Predicate<CavePerson> isPet = cavePerson -> cavePerson.gender.equals("Pet");

可以用

yourStream.filter(isMale).map(...).collect...