如何将 csv 文件映射到列表<T>

How to map csv file to List<T>

我正在尝试读取 CSV 文件的内容并映射到 List<T> 其中 T 与文件具有相同的列名。

class InformationTypes{
    private String Title;
    private String Year;
    private List<String> Genre;
    private String RunTime;
    private String Rating;
    private String Votes;
    private String Director;
    private List<String> Cast;
}

private static List<List<InformationTypes>> allParts;

以下是我尝试阅读和映射的方式:

listInformationTypes = Files
            .lines(Paths.get("imdb.csv"))
            .map(line -> Arrays.asList(line.split(";")))
            .collect(toList());

不幸的是,它没有用。我在这里错过了什么?

文件中的示例数据 imdb.csv:

Title,Year,Genre,RunTime,Rating,Votes,Director,Cast,Gross

In the Heat of the Night,1967,Crime;Drama;Mystery,110,7.9,68739,Norman Jewison,Sidney Poitier;Rod Steiger;Warren Oates;Lee Grant,24.38

Forushande,2016,Drama,124,7.8,52643,Asghar Farhadi,Shahab Hosseini;Taraneh Alidoosti;Babak Karimi;Mina Sadati,2.4

Rogue One,2016,Action;Adventure;Sci-Fi,133,7.8,564143,Gareth Edwards,Felicity Jones;Diego Luna;Alan Tudyk;Donnie Yen,532.18

我建议你根据csv的数据模式创建对象,然后将单个记录转换为每个对象,这意味着每个记录都是一个对象。然后你可以通过流读取你的 csv 并将每条记录保存到列表中。而不是将 csv 读取为字符串并保存到包含当前解决方案的列表中。

如果需要代码示例,请随时告诉我。

如果你坚持使用streams那么你基本上需要一个映射器函数来将文件imdb.csv的每一行映射到[=37的实例=] InformationTypes.

在下面的代码中,我使用record(而不是class),只是为了让人们知道它自JDK 14以来就存在于Java中。它只是让您免于编写 equalstoString(以及其他)等方法。

另请注意,我使用 method reference 从流处理代码中调用 mapper 函数。

我还更改了变量的名称,例如 Title 更改为 title,以遵守 Java naming conventions.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public record InformationTypes(String title,
                               String year,
                               List<String> genre,
                               String runTime,
                               String rating,
                               String votes,
                               String director,
                               List<String> cast) {

    private static InformationTypes mapper(String line) {
        String[] parts = line.split(",");
        String title = parts[0];
        String year = parts[1];
        List<String> genre = Arrays.stream(parts[2].split(";"))
                                   .collect(Collectors.toList());
        String runTime = parts[3];
        String rating = parts[4];
        String votes = parts[5];
        String director = parts[6];
        List<String> cast = Arrays.stream(parts[7].split(";"))
                                  .collect(Collectors.toList());
        return new InformationTypes(title, year, genre, runTime, rating, votes, director, cast);
    }

    public static void main(String[] args) {
        Path path = Paths.get("imdb.csv");
        try (Stream<String> lines = Files.lines(path)) {
            List<InformationTypes> allParts = lines.skip(1L)
                                                   .map(InformationTypes::mapper)
                                                   .collect(Collectors.toList());
            allParts.forEach(System.out::println);
        }
        catch (IOException xIo) {
            xIo.printStackTrace();
        }
    }
}

这是我使用您问题中的示例数据 运行 上述代码时得到的输出。

InformationTypes[title=In the Heat of the Night, year=1967, genre=[Crime, Drama, Mystery], runTime=110, rating=7.9, votes=68739, director=Norman Jewison, cast=[Sidney Poitier, Rod Steiger, Warren Oates, Lee Grant]]
InformationTypes[title=Forushande, year=2016, genre=[Drama], runTime=124, rating=7.8, votes=52643, director=Asghar Farhadi, cast=[Shahab Hosseini, Taraneh Alidoosti, Babak Karimi, Mina Sadati]]
InformationTypes[title=Rogue One, year=2016, genre=[Action, Adventure, Sci-Fi], runTime=133, rating=7.8, votes=564143, director=Gareth Edwards, cast=[Felicity Jones, Diego Luna, Alan Tudyk, Donnie Yen]]