
本文将介绍如何使用 Java 泛型创建一个通用的 CSV 到对象的转换器。通过泛型,我们可以避免为每种需要转换的 Java 类编写重复的代码,从而提高代码的可重用性和可维护性。文章将提供代码示例,并讨论一些关于代码设计和现有 CSV 解析库的建议。
使用 Java 泛型可以创建一个通用的 CSV 工具类,该类可以读取 CSV 文件并将其转换为指定类型的 Java 对象列表。以下是一个简单的 CsvUtils 类的示例:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class CsvUtils<T> {
public List<T> read(final String fileName, Class<T> clazz) throws IOException, ReflectiveOperationException {
List<T> objList = new ArrayList<>();
Path pathToFile = Paths.get(fileName);
try (BufferedReader br = Files.newBufferedReader(pathToFile)) {
String line = br.readLine(); // 读取标题行
if(line == null) return objList;
String[] headers = line.split(",");
while ((line = br.readLine()) != null) {
String[] attributes = line.split(",");
T obj = createObject(attributes, headers, clazz);
objList.add(obj);
}
}
return objList;
}
private T createObject(String[] attributes, String[] headers, Class<T> clazz) throws ReflectiveOperationException {
T obj = clazz.getDeclaredConstructor().newInstance(); // 创建对象实例
// 使用反射设置对象属性 (需要根据实际情况调整)
for(int i = 0; i < attributes.length && i < headers.length; i++){
try {
java.lang.reflect.Field field = clazz.getDeclaredField(headers[i]);
field.setAccessible(true); // 允许访问私有字段
// 类型转换 (根据实际类型进行转换)
Object value = attributes[i];
if(field.getType() == Integer.class || field.getType() == int.class){
value = Integer.parseInt(attributes[i]);
}
field.set(obj, value);
} catch (NoSuchFieldException e) {
// 如果字段不存在,则忽略
System.err.println("Field " + headers[i] + " not found in class " + clazz.getName());
} catch (IllegalAccessException e) {
System.err.println("Cannot access field " + headers[i] + " in class " + clazz.getName());
}
}
return obj;
}
}以下是如何使用 CsvUtils 类读取 Cat 和 Dog 对象的示例:
import java.io.IOException;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException, ReflectiveOperationException {
CsvUtils<Dog> dogCsvUtils = new CsvUtils<>();
List<Dog> myDogs = dogCsvUtils.read("dogs.csv", Dog.class);
for (Dog dog : myDogs) {
System.out.println(dog);
}
CsvUtils<Cat> catCsvUtils = new CsvUtils<>();
List<Cat> myCats = catCsvUtils.read("cats.csv", Cat.class);
for (Cat cat : myCats) {
System.out.println(cat);
}
}
}手动解析 CSV 文件可能会比较繁琐,并且容易出错。 建议使用现有的 CSV 解析库,例如 Apache Commons CSV、OpenCSV、SimpleFlatMapper CSV parser、jackson-dataformat-csv、uniVocity-parsers 等。这些库提供了更丰富的功能和更好的性能,可以大大简化 CSV 文件的解析过程。
立即学习“Java免费学习笔记(深入)”;
例如,使用 Apache Commons CSV:
import org.apache.commons.csv.*;
import java.io.*;
import java.util.*;
public class CsvUtils<T> {
public List<T> read(final String fileName, Class<T> clazz) throws IOException, ReflectiveOperationException {
List<T> objList = new ArrayList<>();
try (Reader reader = new FileReader(fileName);
CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
.withFirstRecordAsHeader()
.withIgnoreHeaderCase()
.withTrim())) {
Map<String, Integer> headerMap = csvParser.getHeaderMap();
for (CSVRecord record : csvParser) {
T obj = createObject(record, headerMap, clazz);
objList.add(obj);
}
}
return objList;
}
private T createObject(CSVRecord record, Map<String, Integer> headerMap, Class<T> clazz) throws ReflectiveOperationException {
T obj = clazz.getDeclaredConstructor().newInstance();
for (Map.Entry<String, Integer> entry : headerMap.entrySet()) {
String headerName = entry.getKey();
String value = record.get(headerName);
try {
java.lang.reflect.Field field = clazz.getDeclaredField(headerName);
field.setAccessible(true);
Object convertedValue = value;
if (field.getType() == Integer.class || field.getType() == int.class) {
convertedValue = Integer.parseInt(value);
}
field.set(obj, convertedValue);
} catch (NoSuchFieldException e) {
System.err.println("Field " + headerName + " not found in class " + clazz.getName());
} catch (IllegalAccessException e) {
System.err.println("Cannot access field " + headerName + " in class " + clazz.getName());
}
}
return obj;
}
}本文介绍了如何使用 Java 泛型创建一个通用的 CSV 到对象的转换器。通过泛型,我们可以避免为每种需要转换的 Java 类编写重复的代码,从而提高代码的可重用性和可维护性。同时,建议使用现有的 CSV 解析库来简化 CSV 文件的解析过程。 在实际应用中,需要根据具体的 CSV 文件格式和 Java 对象结构进行调整,并进行充分的测试和验证。
以上就是使用 Java 泛型实现 CSV 到对象的转换器的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号