简体   繁体   English

用Jackson读取csv时的Java过滤器值

[英]Java filter values when read csv with Jackson

I'm coming to you because I have a problem concerning the reading of a csv and the creation of a map with Jackson. 我来找您是因为我在阅读csv和与Jackson一起创建地图时遇到问题。 In order to read the file and associate it to a map I use the following code: 为了读取文件并将其关联到地图,我使用以下代码:

private static <T, R extends IndexedData<T>> List<R> readFile(File csvFile, Class<R> cls) throws Exception {
    CsvMapper csvMapper = new CsvMapper();
    CsvSchema csvSchema = csvMapper.typedSchemaFor(cls).withHeader().withStrictHeaders(true);
    List list = csvMapper.readerFor(cls)
            .with(csvSchema.withColumnSeparator(';'))
            .with(CsvParser.Feature.SKIP_EMPTY_LINES)
            .readValues(csvFile)
            .readAll();
    return list;
}

however how to filter the data based on the value of an attribute? 但是,如何根据属性值过滤数据?

For example, I have an ID in one column and I want to read and store the line in the map only if this value is equals to "038" 例如,我在一列中有一个ID,并且仅当此值等于“ 038”时,我才想在地图中读取并存储该行

The code used reads the entire file and creates a HashMap with all the values, but I would like to add to the map only certain values ​​with defined criteria. 所使用的代码读取整个文件并创建具有所有值的HashMap,但是我想仅将具有定义条件的某些值添加到映射中。 Knowing that the files have a considerable volume, I can not read all the values ​​and filter the Map later. 知道文件量很大,我无法读取所有值并稍后过滤地图。

Any help will be welcome :) 任何帮助都将受到欢迎:)

cordially 亲切地

I am not sure it is possible to do it directly with the CsvMapper . 我不确定是否可以直接使用CsvMapper An option would be to filter the lines before trying to deserialize them. 一种选择是在尝试反序列化之前对行进行过滤。 Something like this: 像这样:

I use an simple class and csv file here to give you an example 我在这里使用一个简单的类和csv文件给你一个例子

class MyClass {
    private String id;
    private String name;
    // Getters/Setters
}

and the following CSV file 和以下CSV文件

id;name
1;pip
2;pap
3;pop
4;zip
5;zap
6;zop

You could do that: This example only deserialize the lines with a "o" in the name 您可以这样做:此示例仅反序列化名称中带有“ o”的行

public static void main(String[] args) throws Exception {
    readFile(new File("file.csv"));
}



private static List<MyClass> readFile(File csvFile) throws Exception {
    List<String> lines = filterFile(csvFile);

    CsvMapper csvMapper = new CsvMapper();
    CsvSchema csvSchema = csvMapper.typedSchemaFor(MyClass.class).withHeader().withStrictHeaders(true);

    List list = csvMapper.readerFor(MyClass.class)
            .with(csvSchema.withColumnSeparator(';'))
            .with(CsvParser.Feature.SKIP_EMPTY_LINES)
            .readValues(String.join("\n", lines))
            .readAll();

    return list;
}


// This method goes through the file and filter out all lines where the name does not contain an "o"
// It also keeps the header because it is needed for the CsvMapper
private static List<String> filterFile(File csvFile) {
    List<String> list = new ArrayList<>();
    boolean header = true;
    try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
        String line;
        String[] tokens;
        while ((line = br.readLine()) != null) {
            tokens = line.split(";");
            if(header || tokens[1].contains("o")) {
                header = false;
                list.add(line);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return list;
}

Returns 2 MyClass objects with names "pop" and "zop" 返回名称为“ pop”和“ zop”的2个MyClass对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM