5

Is it possible to do via stream API ?

List of Employees directly into a List collection from CSV?

2
  • Yes, it is possible. I suggest you edit your question and post a sample of the contents of your CSV file, as well as your Employee class. Commented Jun 24, 2020 at 17:46
  • I reopened because the linked Question is about a nested map which is a significantly more complicated than the simple list of objects requested here. Commented Jun 24, 2020 at 18:03

1 Answer 1

7

tl;dr

Using a CSV utility such as Apache Commons CSV, each row of incoming data can be passed to a parsing method you write, with the resulting Employee object collected into a 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 method converts data from the CSVRecord to make a Employee object.

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

Details

Yes, you can load a List from a CSV file.

First, grab a CSV parsing utility such as https://commons.apache.org/proper/commons-csv/. You have a variety of such tools to choose from within the Java ecosystem.

Then define a Employee class with a factory method that parses the CSV input. In the case of Apache Commons CSV, that would be a CSVRecord object.

The important parse method of the 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;
}

The entire Employee class source code.

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

And here is a demo of using that factory method to produce a List of Employee records from a CSV file. The main method here first creates a file. Notice the first row is a header row, declaring the name of each column. We use that name in our parsing code.

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

Then we read that newly created file, with Apache Commons CSV parsing each row as a CSVRecord which we pass to the static method Employee.parse. we get back a Employee record.

In our case with Apache Commons CSV, we get an Iterable of CSVRecord objects. We convert that Iterable to a Stream using StreamSupport as discussed in the Question, Convert Iterable to Stream using Java 8 JDK.

The core of the demo code.

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

Entire demo code.

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

When run.

employees = [Employee{ id=ac4f0541-4f39-4b8a-a49b-5e88405da503 | name='Alice' }, Employee{ id=ca4a3950-e7a1-4521-993f-1d4c78ecda8c | name='Bob' }, Employee{ id=67ef39f8-688f-4795-8b41-76d972cad888 | name='Carol' }]

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.