通过 Java Stream API 将 CSV 直接加载到对象 集合中

2023-12-08

是否可以通过流 API 来完成?

将员工列表直接放入 CSV 的列表集合中?


tl;dr

使用 CSV 实用程序,例如Apache 共享 CSV,每一行传入数据都可以传递给您编写的解析方法,并得到结果Employee对象收集到List.

Iterable < CSVRecord > iterable = CSVFormat.RFC4180.withFirstRecordAsHeader().parse( reader );
employees =
        StreamSupport
                .stream( iterable.spliterator() , false )
                .map( ( CSVRecord csvRecord ) -> Employee.parse( csvRecord ) )
                .collect( Collectors.toList() )
;

That Employee.parse方法将数据从CSVRecord做一个Employee object.

UUID id = UUID.fromString( csvRecord.get( "id" ) ) ;
String name = csvRecord.get( "name" ) ;
return new Employee( id , name ) ;

Details

是的,您可以加载List来自 CSV 文件。

首先,获取 CSV 解析实用程序,例如 https://commons.apache.org/proper/commons-csv/。 Java 生态系统中有多种此类工具可供选择。

然后定义一个Employee具有解析 CSV 输入的工厂方法的类。对于 Apache Commons CSV,这将是CSVRecord object.

重要的parse的方法Employee class.

// Parsing from Apache Commons CSV record
static public Employee parse ( CSVRecord csvRecord )
{
    UUID id = UUID.fromString( Objects.requireNonNull( csvRecord.get( "id" ) ) );
    String name = Objects.requireNonNull( csvRecord.get( "name" ) );
    Employee employee = new Employee( id , name );
    Objects.requireNonNull( employee );
    return employee;
}

整个Employee类源代码。

package work.basil.example;

import org.apache.commons.csv.CSVRecord;

import java.util.Objects;
import java.util.UUID;

public class Employee
{
    // Member fields.
    private UUID id;
    private String name;

    // Constructor.
    public Employee ( UUID id , String name )
    {
        this.id = Objects.requireNonNull( id );
        this.name = Objects.requireNonNull( name );
        if ( this.name.isBlank() ) { throw new IllegalArgumentException(); }
    }

    // Parsing from Apache Commons CSV record
    static public Employee parse ( CSVRecord csvRecord )
    {
        UUID id = UUID.fromString( Objects.requireNonNull( csvRecord.get( "id" ) ) );
        String name = Objects.requireNonNull( csvRecord.get( "name" ) );
        Employee employee = new Employee( id , name );
        Objects.requireNonNull( employee );
        return employee;
    }

    // Object overrides.


    @Override
    public String toString ( )
    {
        return "Employee{ " +
                "id=" + id +
                " | name='" + name + '\'' +
                " }";
    }

    @Override
    public boolean equals ( Object o )
    {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        Employee employee = ( Employee ) o;
        return getId().equals( employee.getId() );
    }

    @Override
    public int hashCode ( )
    {
        return Objects.hash( getId() );
    }

    // Getters.
    public UUID getId ( ) { return this.id; }

    public String getName ( ) { return this.name; }
}

这是使用该工厂方法来生成的演示List of EmployeeCSV 文件中的记录。这main这里的方法首先创建一个文件。请注意,第一行是标题行,声明每列的名称。我们在解析代码中使用该名称。

id,name
ac4f0541-4f39-4b8a-a49b-5e88405da503,Alice
ca4a3950-e7a1-4521-993f-1d4c78ecda8c,Bob
67ef39f8-688f-4795-8b41-76d972cad888,Carol

然后我们读取新创建的文件,使用 Apache Commons CSV 将每一行解析为CSVRecord我们将其传递给静态方法Employee.parse。我们得到一个Employee record.

在我们的例子中Apache 共享 CSV,我们得到一个Iterable of CSVRecord对象。我们将其转换为Iterable to a Stream using StreamSupport正如问题中所讨论的,使用 Java 8 JDK 将 Iterable 转换为 Stream.

演示代码的核心。

    List < Employee > employees = List.of(); // Default to empty non-modifiable list.

    Path path = Paths.get( "/Users/basilbourque/csv.txt" );
    try (
            Reader reader = Files.newBufferedReader( path , StandardCharsets.UTF_8 ) ;
    )
    {
        Iterable < CSVRecord > iterable = CSVFormat.RFC4180.withFirstRecordAsHeader().parse( reader );
        employees =
                StreamSupport
                        .stream( iterable.spliterator() , false )
                        .map( ( CSVRecord csvRecord ) -> Employee.parse( csvRecord ) )
                        .collect( Collectors.toList() )
        ;
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }

完整的演示代码。

package work.basil.example;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class EmployeeDemo
{

    public static void main ( String[] args )
    {
        EmployeeDemo app = new EmployeeDemo();
        app.write();
        app.read();
    }

    private void write ( )
    {
        Path path = Paths.get( "/Users/basilbourque/csv.txt" );
        try (
                Writer writer = Files.newBufferedWriter( path , StandardCharsets.UTF_8 ) ;
                CSVPrinter printer = new CSVPrinter( writer , CSVFormat.RFC4180 ) ;
        )
        {
            printer.printRecord( "id" , "name" );
            printer.printRecord( UUID.randomUUID() , "Alice" );
            printer.printRecord( UUID.randomUUID() , "Bob" );
            printer.printRecord( UUID.randomUUID() , "Carol" );
        }
        catch ( IOException ex )
        {
            ex.printStackTrace();
        }
    }

    private void read ( )
    {
        List < Employee > employees = List.of(); // Default to empty non-modifiable list.

        Path path = Paths.get( "/Users/basilbourque/csv.txt" );
        try (
                Reader reader = Files.newBufferedReader( path , StandardCharsets.UTF_8 ) ;
        )
        {
            Iterable < CSVRecord > iterable = CSVFormat.RFC4180.withFirstRecordAsHeader().parse( reader );
            employees =
                    StreamSupport
                            .stream( iterable.spliterator() , false )
                            .map( ( CSVRecord csvRecord ) -> Employee.parse( csvRecord ) )
                            .collect( Collectors.toList() )
            ;
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
        System.out.println( "employees = " + employees );
    }
}

运行时。

员工= [员工{ id=ac4f0541-4f39-4b8a-a49b-5e88405da503 | name='Alice' }, 员工{ id=ca4a3950-e7a1-4521-993f-1d4c78ecda8c | name='Bob' }, 员工{ id=67ef39f8-688f-4795-8b41-76d972cad888 |名称='卡罗尔'}]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 Java Stream API 将 CSV 直接加载到对象 集合中 的相关文章

随机推荐