I've written below codes. I am wondering if there is better way of doing this. My abstract class to read csv file.
public abstract class CsvFile {
public void readCsv(String csvString) throws IllegalAccessException {
String[] csv = csvString.split(",");
List<Field> fields = Arrays.stream(getClass().getDeclaredFields())
.filter(f -> f.isAnnotationPresent(CsvProp.class))
.sorted(Comparator.comparing(o -> Integer.parseInt(o.getName().replaceAll("[^0-9]", ""))))
.collect(Collectors.toList());
for (int i = 0; i < fields.size(); i++) {
Field field = fields.get(i);
try {
field.set(this, csv[i]);
} catch (IndexOutOfBoundsException e) {
field.set(this, "");
}
}
}
And classes that extends it.
public class CsvType1 extends CsvFile {
@CsvProp(name = "csvItem1")
public String item1;
@CsvProp(name = "csvItem2")
public String item2;
}
public class CsvType2 extends CsvFile {
@CsvProp(name = "csvItem1")
public String item1;
@CsvProp(name = "csvItem2")
public String item2;
@CsvProp(name = "csvItem3")
public String item3;
}
And utility class to read file.
public class CsvUtils {
public static List<CsvFile> readCsvFile(Class<? extends CsvFile> fileClass, String filePath) throws IOException, ReflectiveOperationException {
List<CsvFile> list = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
CsvFile csvFile = fileClass.getConstructor().newInstance();
csvFile.readCsv(line);
list.add(csvFile);
}
return list;
}
}
Usage:
public static void main(String[] args) throws IOException, ReflectiveOperationException {
List<CsvFile> f1 = CsvUtils.readCsvFile(CsvType1.class, "C:/csvfile1.csv");
List<CsvFile> f2 = CsvUtils.readCsvFile(CsvType2.class, "C:/csvfile2.csv");
for (CsvFile f : f1) {
CsvType1 castedF = (CsvType1) f;
System.out.println(castedF.item1);
}
}
Is there a way to use it without casting by changing return type? I want use like this:
List<CsvType1> f1 = CsvUtils.readCsvFile(CsvType1.class, "C:/csvfile1.csv");
for (CsvType1 noCastF : f1) {
System.out.println(noCastF.item1);
}
Use
public static <T extends CsvFile> List<T> readCsvFile(Class<T> fileClass, String filePath) throws IOException, ReflectiveOperationException
Also. Why not use existing library? Your is not proper csv parser.