Home > Net >  Parsing text file with Stream API Java
Parsing text file with Stream API Java

Time:04-23

I have this file to process and I'm trying to figure out how to read the second line as a different object. At the end of the row, the last item is the number of buses. Second line, fourth line and so on should contain idBus and noOfBus separated by commas.

1,Harvard University,2
1,140,2,56
2,Massachusetts Institute of Technology,2
1,240,5,56
3,University of California Berkeley,3
1,112,2,56,3,28
4,Columbia University,4
1,84,2,84,3,84,7,28

Based on these classes

 class University {
    public int idUniversity;
    public String nameOfUniversity;
    public int noOfBuses;
 }

 class Bus {
    public int idBus;
    public int noOfBus;
 }

I want a function to process a List for all the bus and universities lines from CSV File. It's must use Stream API. I don't know if it's possible or how to proceed.

Of course, changes can be made based on classes but keep the variables and not add anything extra.

I think the most convenient thing would be to go through the file and get two lists based on the two classes (University and Bus) and finally add them in a THIRD list and then to do the processing but I don't know how.

Based on this file I have to do processing with Stream API such as "sort buses by ID" or "which universities have more busses?" or "which bus goes to several universities?".

That's what I've been trying to do. Normally this is how I would have gone through a CSV file.

private static List<University> readListOfUniversities() throws IOException {
    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(PATH_UNIVERSITIES_TEXT_FILE))) {
        return bufferedReader.lines().map(line -> {
            String[] tokens = line.split(",");
            var idUniversity = Integer.parseInt(tokens[0]);
            var nameOfUniversity = tokens[1].trim();
            var noOfBuses = Integer.parseInt(tokens[2]);
            var university = new University(idUniversity, nameOfUniversity, noOfBuses);
            return university;
        }).collect(Collectors.toList());
    }
}

Like this one:

1,Harvard University,2
2,Massachusetts Institute of Technology,2
3,University of California Berkeley,3
4,Columbia University,4

CodePudding user response:

Here's how I would do it (I made slight modifications to your classes)

public class University {
    private int id;
    private String name;
    private List<Bus> busList;
    //let the constructor do the work
    public University(String [] data, List<Bus> busList) {
        id = Integer.parseInt(data[0]);
        name = data[1];
        this.busList = busList; 
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public List<Bus> getBusList() {
        return busList;
    }

    @Override
    public String toString() {
        return "University [id="   id   ", name="   name   ", busList="   busList   "]";
    }
    
}

public class Bus {
    private int id;
    private int num;
    
    public Bus(int id, int num) {
        this.id = id;
        this.num = num;
    }
    
    public int getId() {
        return id;
    }

    public int getNum() {
        return num;
    }
    //Method to parse the data into usuable objects
    public static List<Bus> generateBusInfo(String [] data) {
        List<Bus> buses = new ArrayList<>();
        for (int i = 0; i < data.length-1; i =2) {
            int id = Integer.parseInt(data[i]);
            int num = Integer.parseInt(data[i 1]);
            buses.add(new Bus(id, num));
        }
        return buses;
    }

    @Override
    public String toString() {
        return "Bus [id="   id   ", num="   num   "]";
    }
}


public static void main(String[] args) throws IOException {
    //This is just so I dont have to bother with creating a file.
    String input = "1,Harvard University,2\n"   
            "1,140,2,56\n"   
            "2,Massachusetts Institute of Technology,2\n"   
            "1,240,5,56\n"   
            "3,University of California Berkeley,3\n"   
            "1,112,2,56,3,28\n"   
            "4,Columbia University,4\n"   
            "1,84,2,84,3,84,7,28\n";
    List<University> universities = new ArrayList<>();
    //replace StringReader with a FileReader to the path of your file.
    try(BufferedReader reader = new BufferedReader(new StringReader(input))) {
        //read the first line
        String line = reader.readLine();
        while (line != null) { //keep reading until you're done
            String [] uniData = line.split(","); //convert string into an array
            line = reader.readLine(); //read the next line
            if (line != null) {
                String [] busData = line.split(","); //convert
                List<Bus> busList = Bus.generateBusInfo(busData); //make busses
                universities.add(new University(uniData, busList)); //create university and add it to the list
                line = reader.readLine(); //read the next line
            }
        }
    }
    
    //output the list
    for (University uni : universities) {
        System.out.println(uni);
    }
}

You could also read the Universities and buses into Maps for easier access.

  • Related