我正在尝试创建一个简单的类来读取csv文件并将内容存储在一个
ArrayList<ArrayList<T>>.
Run Code Online (Sandbox Code Playgroud)
我正在创建一个泛型类CsvReader,以便我可以处理不同类型的数据:int,double,String.如果我有一个双打的csv文件,我想象我会像这样使用我的班级:
//possible method 1
CsvReader<Double> reader = new CsvReader<Double>();
ArrayList<ArrayList<Double>> contents = reader.getContents();
//possible method 2
CsvReader reader = new CsvReader(Double.class);
ArrayList<ArrayList<Double>> contents = reader.getContents();
Run Code Online (Sandbox Code Playgroud)
但是方法1不起作用,因为类型擦除会阻止您编写类似的代码
rowArrayList.add(new T(columnStringValue));
Run Code Online (Sandbox Code Playgroud)
但我甚至无法在Double.class解决方案中进行传递.问题是,真正发生的是我需要在具有以下属性的类型上"参数化"(在一般意义上,不是技术java泛型意义上):它有一个接受单个String参数的ctor .也就是说,要在Double csv文件上创建行ArrayLists,我需要写:
StringTokenizer st = new StringTokenizer(line,",");
ArrayList<Double> curRow = new ArrayList<Double>();
while (st.hasMoreTokens()) {
curRow.add(new Double(st.nextToken());
}
Run Code Online (Sandbox Code Playgroud)
传入Double.class后,我可以使用它的String ctor
Constructor ctor = c.getConstructor(new Class[] {String.class});
Run Code Online (Sandbox Code Playgroud)
但这有两个问题.最重要的是,这是一个通用构造函数,它将返回一个Object类型,然后我无法将其转换为Double.其次,我将缺少"类型"检查,因为我要求我传入类中有一个String arg构造函数.
我的问题是:我如何正确实现这个通用的CsvReader?
谢谢,约拿
我不确定通用的CSV阅读器这么简单易用(顺便说一下,创建).
我想到的第一个问题是:如果CSV包含三列,那么该怎么办:首先是整数,然后是字符串,最后是日期?您将如何使用通用CSV阅读器?
无论如何,假设您想要创建一个CSV阅读器,其中所有列都是相同类型.正如您所说,您无法在"接受String构造函数" 的类型上对类进行参数化.Java只是不允许这样做.使用反射的解决方案是一个良好的开端.但是如果你的类没有String在其构造函数中使用as参数呢?
在这里你可以有一个替代方案:一个解析器,它将获取你的String并返回一个正确类型的对象.创建一个通用接口,并为要爬网的类型进行一些实现:
public interface Parser<T> {
T parse(String value);
}
Run Code Online (Sandbox Code Playgroud)
然后,实施:
public class StringParser implements Parser<String> {
public String parse(String value) {
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您的CSV阅读器可以将其Parser作为其参数之一.然后,它可以使用此解析器将每个String转换为Java对象.
有了这个解决方案,你就可以摆脱不那么漂亮的反射.你可以转换为任何类型,你只需要实现一个Parser.
您的读者将如下所示:
public CSVReader<T> {
Parser<T> parser;
List<T> getValues() {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,回到CSV文件可以有多种类型的问题,只需稍微改进您的阅读器.您只需要一个解析器列表(每列一个),而不是解析所有列的解析器列表.
希望有所帮助:-)
| 归档时间: |
|
| 查看次数: |
3042 次 |
| 最近记录: |