简体   繁体   English

Apache Commons CSV 不会忽略缺失的列

[英]Apache Commons CSV doesn't ignore missing column

Using Apache Commons CSV for parsing, but doesn't ignore missing column and throws exception.使用 Apache Commons CSV 进行解析,但不会忽略缺失的列并抛出异常。

with this sample data:使用此示例数据:

name age
Ali 35
John 25
Vahid 75

Below code record.get(DataColumns.surname) throws java.lang.IllegalArgumentException: Mapping for surname not found, expected one of [name, surname, age] .下面的代码record.get(DataColumns.surname)抛出java.lang.IllegalArgumentException: Mapping for surname not found, expected one of [name, surname, age] I need it returns null, optional or default value.我需要它返回空值、可选值或默认值。 Is there any option?有什么选择吗? I know it is possible with record.toMap().get(DataColumns.surname.name()) but its performance will not be good:我知道record.toMap().get(DataColumns.surname.name())是可能的,但它的性能不会很好:

...
enum DataColumns { name, surname, age }
...
Reader in = new BufferedReader(new FileReader(fileName));

try (CSVParser records = CSVFormat.TDF
                .withDelimiter(' ')
                .withIgnoreSurroundingSpaces()
                .withAllowDuplicateHeaderNames(false)
                .withIgnoreHeaderCase()
                .withTrim()
                .withHeader(DataColumns.class)
                .withFirstRecordAsHeader()
                .withSkipHeaderRecord()
                .withAllowMissingColumnNames(false)
                .withIgnoreEmptyLines()
                .parse(in)) {

   for (CSVRecord record : records) {
       String name = record.get(DataColumns.name);
       String surname = record.get(DataColumns.surname);
       Short age = Short.valueOf(record.get(DataColumns.age)); 
   }
}

...

You might try using record.isMapped(columnName) to check if the column exists, recording into a variable so you don't have to check again every line.您可以尝试使用record.isMapped(columnName)来检查该列是否存在,记录到一个变量中,这样您就不必再次检查每一行。

Another option would be to use records.getHeaderNames() and store it into a variable once, before the loop, maybe even using a Set<String> for an extra kick of existance checking performance: Set<String> headerNames = new HashSet<>(records.getHeaderNames()) .另一种选择是使用records.getHeaderNames()并在循环之前将其存储到变量中一次,甚至可能使用Set<String>来提高存在性检查性能: Set<String> headerNames = new HashSet<>(records.getHeaderNames())

Then, you can use the resulting variable inside the loop by calling headerNames.contains(columnName) to check whether the column exists or not.然后,您可以通过调用headerNames.contains(columnName)在循环内使用结果变量来检查该列是否存在。

Plese, see: https://javadoc.io/doc/org.apache.commons/commons-csv/latest/org/apache/commons/csv/CSVRecord.html请参阅: https ://javadoc.io/doc/org.apache.commons/commons-csv/latest/org/apache/commons/csv/CSVRecord.html

There is method: record.get(String) while you gave enum instead.有方法:record.get(String) 而你给了枚举。

Try record.get(DataColumns.name.name())试试 record.get(DataColumns.name.name())

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

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