一个经过个人优化的CSV读取器
利用Java反射机制和Cache实现读取的优化
package util;
import com.csvreader.CsvReader;
import com.sun.istack.internal.Nullable;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
/**
* Created by heleninsa on 2017/3/2.
*/
public class CSVUtil {
public static void main(String[] args) {
try {
Map<String, String> others = new HashMap<>();
others.put("Adj Close", "adjClose");
System.out.println(csv_file_read("/Users/heleninsa/Desktop/AQMRequest/软工III/量化交易/股票历史数据ALL.csv", AQMBean.class, others).size());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* For Storage of Class's Method.
* On suppose of avoid get method operation
*/
private static Map<String, Method> method_cache = new HashMap<>();
private static Field[] property_fields_local_cache;
/**
*
* @param csv_file : file path
* @param bean : bean type
* @param columns : default is null. Key is column name, value is property_name. To avoid different value of this two name
* @param <T> : Type of Bean to Create
* @return : List of Bean
* @throws IOException
* @throws PropertySetException
* @throws NoDefaultConstructorException
* @throws NoSuchMethodException
*/
public final static <T extends CSVBean> List<T> csv_file_read(final String csv_file, Class<T> bean, @Nullable Map<String, String> columns) throws IOException, PropertySetException, NoDefaultConstructorException, NoSuchMethodException {
CsvReader reader = new CsvReader(csv_file);
reader.readHeaders();
List<T> record_list = new ArrayList<T>();
try {
initMethodList(bean);
while (reader.readRecord()) {
T object;
object = (T) getBean(bean);
setProperty(reader, object, columns);
if (object.filter()) {
record_list.add(object);
}
}
} catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
throw new NoDefaultConstructorException();
} finally {
reader.close();
method_cache.clear();
}
return record_list;
}
/**
* 预加载类方法
*
* @param cls
* @param <T>
* @throws NoSuchMethodException
*/
private final static <T extends CSVBean> void initMethodList(Class<T> cls) throws NoSuchMethodException {
property_fields_local_cache = cls.getDeclaredFields();
//类属性区域方法设置
for (Field each : property_fields_local_cache) {
String property_name = each.getName();
String method_name = getSetMethodName(property_name);
//获取Set方法
Method method;
if ((method = cls.getMethod(method_name, String.class)) != null) {
method_cache.put(property_name, method);
}
}
}
private final static <T extends CSVBean> CSVBean getBean(Class<T> bean) throws IllegalAccessException, InvocationTargetException, InstantiationException {
return (T) bean.getConstructors()[0].newInstance();
}
/**
* 设置Bean的属性
*
* @param row : CsvReader 指引
* @param bean : 要设置的Bean
* @param columns : 额外的一些columns
* @throws PropertySetException
* @throws IOException
*/
private final static void setProperty(CsvReader row, CSVBean bean, Map<String, String> columns) throws PropertySetException, IOException {
for (Field each : property_fields_local_cache) {
String property_name = each.getName();
String property_value;
try {
property_value = row.get(firstUpper(property_name));
} catch (IOException e) {
//No such property
continue;
}
setSingleProperty(bean, property_name, property_value);
}
setPropertyByMap(row, bean, columns);
}
/**
* 通过Map 设置
*
* @param row
* @param bean
* @param column
* @throws IOException
* @throws PropertySetException
*/
private final static void setPropertyByMap(CsvReader row, CSVBean bean, Map<String, String> column) throws IOException, PropertySetException {
Set<String> keys = column.keySet();
for (String key : keys) {
String property_value = row.get(key);
String property_name = column.get(key);
setSingleProperty(bean, property_name, property_value);
}
}
/**
* 设置单个属性
*
* @param bean
* @param property_name
* @param property_value
* @throws PropertySetException
*/
private static void setSingleProperty(CSVBean bean, String property_name, String property_value) throws PropertySetException {
Method method;
try {
if ((method = method_cache.get(property_name)) != null) {
method.invoke(bean, property_value);
}
} catch (Exception e) {
throw new PropertySetException();
}
}
private static String getSetMethodName(String property) {
return "set" + firstUpper(property.replace("\\s", ""));
}
private static String firstUpper(String string_to_deal) {
return string_to_deal.substring(0, 1).toUpperCase() + string_to_deal.substring(1);
}
public static abstract class CSVBean {
/**
* @return Match your filter or not
*/
public boolean filter() {
return true;
}
}
public static class PropertySetException extends Exception {
public PropertySetException() {
super("无法成功设置变量,请检查你的参数设置和传入参数是否正确。");
}
}
public static class NoDefaultConstructorException extends Exception {
public NoDefaultConstructorException() {
super("找不到默认构造函数。");
}
}
}