我来找你是因为我在阅读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;
}
但是如何根据属性值过滤数据?
例如,我在一列中有一个ID,只有当此值等于&#34; 038&#34;
时,我才想在地图中读取并存储该行使用的代码读取整个文件并创建一个包含所有值的HashMap,但我想仅向地图添加具有已定义条件的特定值。 知道文件有相当大的音量,我无法读取所有值并稍后过滤地图。
欢迎任何帮助:)
亲切
答案 0 :(得分:0)
我不确定是否可以直接使用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;
}
返回名为“pop”和“zop”
的2个MyClass
个对象