I have an assignment, where I need to read a CSV file. I know that the first line of the CSV file will have the following information:
LabelA,LabelB,LabelC,LabelD
and that all of the lines below will have the corresponding information, so all the following lines of the CSV file looks like this:
InfoA,InfoB,InfoC,InfoD
I have created a Class that stores all of that information, and then I need to create a HashMap to store all of those objects, each object with the information of a different line, however, the CSV File that I will be reading has a randomized order of the columns, so I might receive a CSV File that has the first line as:
LabelD,LabelA,LabelB,LabelC
Which would make the following lines as:
InfoD,InfoA,InfoB,InfoC
How can I approach this? Regardless of the order of the columns of the CSV file, I need to correctly store that information in an Object.
Before this assignment, the order of the columns was always the same, so I was storing each line on a String, then splitting the String, and then putting the information in that order in the constructor of the object, but I can no longer do this, since the order will be randomized.
For further clarification, please ask.
UPDATE: I forgot to mention, I am not allowed to use any dependency other than java.io.File , java.util.Scanner , and java.util.HashMap
CodePudding user response:
If you want to use core java only you can try this:
public class Main {
public static void main(String[] args) {
StringReader reader = new StringReader(
"""
Col1,Col2
aa,bb
cc,dd
""");
Scanner scanner = new Scanner(reader);
String[] header = scanner.nextLine().split(",");
Map<String, Integer> mapping = new HashMap<>();
for (int i = 0; i < header.length; i ) {
mapping.put(header[i].trim(), i);
}
List<MyBean> list = new ArrayList<>();
while (scanner.hasNext()) {
String[] data = scanner.nextLine().split(",");
MyBean value = new MyBean();
value.setColum1(data[mapping.get("Col1")]);
value.setColum2(data[mapping.get("Col2")]);
list.add(value);
}
System.out.println(list);
}
@Data
public static class MyBean {
private String colum1;
private String colum2;
}
}
CodePudding user response:
I don't understand your intended use of 'a hash map' - what is the key? But in any case, there are a number of possibilities - for example, sort the labels into some standard order (maybe alphabetical) and then sort the 'info' into the same order.
Thus for example if LabelA is the 3rd column, then you know that the 3rd column has InfoA, but you want to use that as the first argument to your constructor.
CodePudding user response:
Here is a little example:
public class Main {
public static void main(String[] args) {
CSVReader csvReader = new CSVReader(new StringReader(
"""
Col1, Col2
aa, bb
cc, dd
"""));
CsvToBean<MyBean> parser = new CsvToBeanBuilder<MyBean>(csvReader)
.withType(MyBean.class).build();
List<MyBean> beans = parser.parse();
System.out.println(beans);
}
@Data
public static class MyBean {
@CsvBindByName(column = "Col1")
private String colum1;
@CsvBindByName(column = "Col2")
private String colum2;
}
}
Here is required dependencies:
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
Lombock is optional. You can create your bean the way you want.