
本文将介绍如何利用 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(String fileName, Class<T> clazz) throws IOException, ReflectiveOperationException {
List<T> objectList = new ArrayList<>();
Path pathToFile = Paths.get(fileName);
try (BufferedReader br = Files.newBufferedReader(pathToFile)) {
String line = br.readLine(); // Skip header line
while ((line = br.readLine()) != null) {
String[] attributes = line.split(",");
T obj = createObject(attributes, clazz);
objectList.add(obj);
}
}
return objectList;
}
private T createObject(String[] attributes, Class<T> clazz) throws ReflectiveOperationException {
// This is a basic implementation. Consider using a more robust approach, like reflection.
// Also consider using a CSV parsing library.
T obj = clazz.getDeclaredConstructor().newInstance();
// Assuming the class has a constructor with no arguments.
// And assuming the class has setters for each attribute in the CSV file.
// The order of the attributes in the CSV file must match the order of the setters in the class.
// This is a very simple example and should be improved for real-world use.
if (attributes.length > 0) {
try {
clazz.getMethod("setId", int.class).invoke(obj, Integer.parseInt(attributes[0]));
} catch (NoSuchMethodException e) {
// Handle exception, e.g., if the class does not have an setId method
}
}
if (attributes.length > 1) {
try {
clazz.getMethod("setName", String.class).invoke(obj, attributes[1]);
} catch (NoSuchMethodException e) {
// Handle exception, e.g., if the class does not have a setName method
}
}
return obj;
}
}在这个示例中,CsvUtils 类使用泛型类型 T。 read 方法接受文件名和类类型 Class<T> 作为参数,并返回 T 类型的对象列表。 createObject 方法负责将 CSV 行转换为 T 类型的对象。
以下是如何使用 CsvUtils 类的示例:
立即学习“Java免费学习笔记(深入)”;
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("MyDogs_V1.csv", Dog.class);
for (Dog dog : myDogs) {
System.out.println(dog);
}
CsvUtils<Cat> catCsvUtils = new CsvUtils<>();
List<Cat> myCats = catCsvUtils.read("MyCats_V1.csv", Cat.class);
for (Cat cat : myCats) {
System.out.println(cat);
}
}
}在这个示例中,我们创建了 CsvUtils<Dog> 和 CsvUtils<Cat> 的实例,并分别使用它们读取 "MyDogs_V1.csv" 和 "MyCats_V1.csv" 文件。
以下是使用 Apache Commons CSV 库的示例:
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class CsvUtils<T> {
public List<T> read(String fileName, Class<T> clazz) throws IOException, ReflectiveOperationException {
List<T> objectList = new ArrayList<>();
try (
Reader reader = Files.newBufferedReader(Paths.get(fileName));
) {
Iterable<CSVRecord> records = CSVFormat.DEFAULT
.withHeader("Id","Name") //define header names
.withFirstRecordAsHeader()
.parse(reader);
for (CSVRecord record : records) {
T obj = createObject(record, clazz);
objectList.add(obj);
}
}
return objectList;
}
private T createObject(CSVRecord record, Class<T> clazz) throws ReflectiveOperationException {
// This is a basic implementation. Consider using a more robust approach, like reflection.
// Also consider using a CSV parsing library.
T obj = clazz.getDeclaredConstructor().newInstance();
// Assuming the class has a constructor with no arguments.
// And assuming the class has setters for each attribute in the CSV file.
// The order of the attributes in the CSV file must match the order of the setters in the class.
// This is a very simple example and should be improved for real-world use.
try {
clazz.getMethod("setId", int.class).invoke(obj, Integer.parseInt(record.get("Id")));
} catch (NoSuchMethodException e) {
// Handle exception, e.g., if the class does not have an setId method
}
try {
clazz.getMethod("setName", String.class).invoke(obj, record.get("Name"));
} catch (NoSuchMethodException e) {
// Handle exception, e.g., if the class does not have a setName method
}
return obj;
}
}在这个示例中,我们使用 CSVFormat 类来配置 CSV 解析器,并使用 CSVRecord 类来访问 CSV 行中的数据。
通过使用 Java 泛型和 CSV 解析库,我们可以创建一个通用的 CSV 文件到 Java 对象转换器,从而避免为每种需要转换的类编写重复的代码。在实际应用中,需要根据具体的需求选择合适的 CSV 解析库和对象创建方式,并处理可能出现的异常。 此外,为了提高代码的可维护性和可扩展性,应该尽量避免硬编码,而是使用配置文件或注解等方式来指定 CSV 文件和 Java 对象之间的映射关系。
以上就是使用 Java 泛型创建 CSV 到对象的转换器的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号