BufferedReader - Output columns in in different order JAVA

386 Views Asked by At

I have 2 csv files with column 'car', 'bike', 'tractor' etc

The below code prints out data from the csv which works fine, however cvs 1 prints out in a different or to csv 2 so I want to arrange the columns in a different order.

From this code, how can I organise the data to print out in order of which column I want first, second etc.

BufferedReader r = new BufferedReader(new InputStreamReader(str));
          Stream lines = r.lines().skip(1);

          lines.forEachOrdered(
              line -> {
               line= ((String) line).replace("\"", "");
                 ret.add((String) line);

The columns print out like this:

csv 1

Car, Bike, Tractor, Plane, Train

csv 2

Bike, Plane, Tractor, Train, Car,

but I want to manipulate the code so the two csv files print out in the same order like;

Bike, Plane ,Tractor, Train, Car

I can't use the likes of col[1],col[3], as the two files are in different or so I would need to call them by column name in the csv file so col["Truck"] etc

Or is there another way. Like creating a new list from the csv 1 output and rearranging ?

I haven't used BufferedReader much so I'm not sure if this is a silly question and there's a simple solution

1

There are 1 best solutions below

2
tucuxi On

A BufferedReader reads lines, and does not care for the content of those lines. So this code will simply save lines into ret as it is reading them:

 List<String> ret = new ArrayList<>();
 try (BufferedReader r = new BufferedReader(new InputStreamReader(str))) {
     r.lines().skip(1).forEachOrdered(l -> ret.add(l.replace("\"", ""));
 }
 // now ret contains one string per CSV line, excluding the 1st

(This is somewhat better than your code in that it is guaranteed to close the reader correctly, and does not require any casts to string).

If your CSV lines do not contain any , characters that are not separators, you can modify the above code to split lines into columns; which you can then reorder:

 List<String[]> ret = new ArrayList<>(); // list of string arrays
 try (BufferedReader r = new BufferedReader(new InputStreamReader(str))) {
     r.lines().skip(1).forEachOrdered(l -> 
        ret.add(l.replace("\"", "").split(",")); // splits by ','
 }
 // now ret contains a String[] per CSV line, skipping the 1st;
 // with ret.get(0)[1] being the 2nd column of the 1st non-skipped line

 // this will output all lines, reversing the order of columns 1 and 2:
 for (String[] line : ret) {
    System.out.print(line[1] + ", " + line[0]);
    for (int i=2; i<line.length; i++) System.out.print(", " + line[i]);
    System.out.println();
 }

If your CSV lines can contain ,s that are not delimiters, you will need to learn how to correctly parse (=read) CSVs, and that requires significantly more than a BufferedReader. I would recommend using an external library to handle this correctly (for there are many types of CSVs in the wild). In particular, using Apache Commons CSV, things are relatively straightforward:

try (Reader in = new FileReader("path/to/file.csv")) {
   Iterable<CSVRecord> records = CSVFormat.RFC4180.parse(in);
   for (CSVRecord record : records) {
       String columnOne = record.get(0);
       String columnTwo = record.get(1);
   }
}