如果我有一个 Stream<Class>,我如何访问 类' 的固有信息,例如变量和数组?

If I have a Stream<Class>, how can I access the classes' inherent information such as variables and arrays?

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

public class Person {
   public final int num;
   public final String name;
   public final String gender;
   public final int age;

   public Person (int aNum, String aName, String aGender, int anAge){
      this.num = aNum;
      this.name = aName;
      this.gender = aGender;
      this.age = anAge;
   }

   public static Person 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 Person(numA, nameA, genderA, ageA);
   }
}

单个人的数据来自 csv 文件中名为 people.csv:

的一行
| Num | Name   | Gender  |Age  |
| --- | ----   | ------  | --- |
| 1   | Fred   | Male    | 41  |
| 2   | Wilma  | Female  | 36  |
| 3   | Barney | Male    | 38  |
| 4   | Betty  | Female  | 35  |

这是我的实际问题。我有一个名为 People 的接口,它有一个名为 getGenderCount 的函数。此函数应通过 Person 对象并检索每个性别的计数图。

static Function<Stream<Person>,Map<String,Long>> getGenderCount = null;

我的问题是我无法理解如何流式传输整个 class 对象的正确语法。我事先使用过原始流。执行 .map(x -> x.split(",")) 之类的拆分是行不通的,因为它属于 String 类型而不是 Person。

我建议的解决方案如下所示:

e -> e.map(x -> x.split(","))
.skip(1) // skips the title line
.filter(x -> x.length == 4)
.collect(Collectors.groupingBy(x -> x[2], Collectors.counting()));

但它应该映射一个 Person 对象 information.I 除了流操作和语法之外,我不想改变我目前拥有的任何东西。我想了解如何从 Person 中提取变量并在 Stream 中找到它们。

这会如你所愿吗?

Files.lines(Paths.get("people.csv"))
.skip(1)
.map(Person::lineValues) // this method must handle "|" divider chars
.collect(Collectors.groupingBy(Person::getGender, Collectors.counting()));

您需要使用 mapfilterforeach 等常用方法对流进行操作,然后才能使用标准访问操作。

Stream<Person> people;
people = ...; // initialize stream with some data

// iterate over stream and access each element
people.forEach(person -> { System.out.println(person.name); });

函数 getGenderCount 获取 Person 流作为输入,并 returns 包含性别及其频率的地图。

此外,在Java中,字符串不能直接赋值给int。需要转换。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Person {
    public final int num;
    public final String name;
    public final String gender;
    public final int age;

    public Person(int aNum, String aName, String aGender, int anAge) {
        this.num = aNum;
        this.name = aName;
        this.gender = aGender;
        this.age = anAge;
    }

    public static Person lineValues(String line) {
        String array[] = line.split(",");
        int numA = Integer.parseInt(array[0]);
        String nameA = array[1];
        String genderA = array[2];
        int ageA = Integer.parseInt(array[3]);
        return new Person(numA, nameA, genderA, ageA);
    }

    static Function<Stream<Person>, Map<String, Long>> getGenderCount = people -> {
        return people.collect(Collectors.groupingBy((person -> person.gender), Collectors.counting()));
    };

    public static void main(String args[]) {
        try {
            Stream<Person> people = Files.lines(Paths.get("people.csv"))
                    .map(line -> { System.out.println(line); return line;}) // just to show input
                    .skip(1) // remove first line
                    .map(line -> line.substring(line.indexOf("|") + 1)) // remove first '|' and in front
                    .map(line -> line.substring(0, line.lastIndexOf("|"))) // remove last '|' and behind
                    .map(line -> line.replace(" ", "")) // remove spaces, can cause trouble with spaces within names
                    .map(line -> line.replace("|", ",")) // change pipe symbols into commas
                    .map(line -> Person.lineValues(line)); // transform lines into persons
            Map<String, Long> genderCount = Person.getGenderCount.apply(people);
            System.out.println(genderCount);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

生产

$ javac Person.java
$ java Person      
| Num | Name   | Gender | Age|
| 1   | Fred   | Male   | 41 |
| 2   | Wilma  | Female | 36 |
| 3   | Barney | Male   | 38 |
| 4   | Betty  | Female | 35 |
{Male=2, Female=2}
$