采用CSV Reader, 基于Java Bean和反射的CSV文件读取器

来源:互联网 发布:夏普哪个好 知乎 编辑:程序博客网 时间:2024/05/18 20:36
一个经过个人优化的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("找不到默认构造函数。");        }    }}

1 0