Значения фильтра Java при чтении CSV с Джексоном - PullRequest
0 голосов
/ 27 апреля 2018

Я иду к вам, потому что у меня проблема с чтением CSV и созданием карты с Джексоном. Чтобы прочитать файл и связать его с картой, я использую следующий код:

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;
}

однако как отфильтровать данные по значению атрибута?

Например, у меня есть идентификатор в одном столбце, и я хочу прочитать и сохранить строку на карте, только если это значение равно "038"

Используемый код читает весь файл и создает HashMap со всеми значениями, но я хотел бы добавить на карту только определенные значения с определенными критериями. Зная, что файлы имеют значительный объем, я не могу прочитать все значения и отфильтровать карту позже.

Любая помощь будет приветствоваться:)

1012 * приветливо *

1 Ответ

0 голосов
/ 27 апреля 2018

Я не уверен, что это можно сделать напрямую с помощью CsvMapper. Можно было бы отфильтровать строки, прежде чем пытаться десериализовать их. Как то так:

Я использую простой класс и CSV-файл, чтобы привести пример

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

и следующий CSV-файл

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

Вы можете сделать это: в этом примере десериализуются только строки с «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;
}

Возвращает 2 MyClass объектов с именами "pop" и "zop"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...