Java 具有复杂bean结构的openCSV
我尝试用openCSV映射嵌套bean结构。我找到了注释,但是如果嵌套bean被多次使用,这似乎不起作用 我有什么办法来解决这个问题 示例(根据上面链接的文档改编) 要映射的数据结构:Java 具有复杂bean结构的openCSV,java,opencsv,Java,Opencsv,我尝试用openCSV映射嵌套bean结构。我找到了注释,但是如果嵌套bean被多次使用,这似乎不起作用 我有什么办法来解决这个问题 示例(根据上面链接的文档改编) 要映射的数据结构: title,author1 given name,author1 surname,author2 given name,author2 surname Space Opera 2.0,Andrew,Jones,Hanna,Smith 我想买以下的豆子 public class Book { @CsvBi
title,author1 given name,author1 surname,author2 given name,author2 surname
Space Opera 2.0,Andrew,Jones,Hanna,Smith
我想买以下的豆子
public class Book {
@CsvBindByName
private String title;
// TODO: How to bind author1 and author2?
private Author author1;
private Author author2;
// Accessor methods go here.
}
public class Author {
// TODO: can I somehow use a prefix/Regex for the column here to differentiate between author1 and author2?
@CsvBindByName(column = "author[1/2] given name")
private String givenName;
@CsvBindByName(column = "author[1/2] surname")
private String surname;
// Accessor methods go here.
}
您可以使用自定义的“ColumnPositionMappingStrategy”。重写“populateNewBean”方法,该方法接受字符串[](csv的行),并可以从中形成任何对象
“@CsvRecurse”应该适用于OpenCSV 5.0 btw。这里是另一个选项: opencsv库有很多有用且灵活的注释,但是在这个特定的例子中,我不会使用任何注释 相反,我将使用opencsv类。使用此选项将允许您保留两个
书籍
和作者
类。我唯一要做的更改是向每个类添加构造函数,如下所示:
书籍:
作者:
public class Author {
private final String givenName;
private final String surname;
public Author(String givenName, String surname) {
this.givenName = givenName;
this.surname = surname;
}
public String getGivenName() {
return givenName;
}
public String getSurname() {
return surname;
}
}
要从CSV文件填充Book
对象列表,请执行以下操作:
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import com.opencsv.CSVReaderHeaderAware;
import com.opencsv.exceptions.CsvValidationException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
...
public static void main(String[] args) throws FileNotFoundException,
IOException, CsvValidationException {
String bookFile = "/path/to/titles.csv";
CSVReaderHeaderAware csvReader = new CSVReaderHeaderAware(new FileReader(bookFile));
List<Book> books = new ArrayList();
Map<String, String> bookRecord;
while ((bookRecord = csvReader.readMap()) != null) {
books.add(handleBook(bookRecord));
}
}
private static Book handleBook(Map<String, String> bookRecord) {
Author author1 = new Author(
bookRecord.get("author1 given name"),
bookRecord.get("author1 surname")
);
Author author2 = new Author(
bookRecord.get("author2 given name"),
bookRecord.get("author2 surname")
);
return new Book(bookRecord.get("title"), author1, author2);
}
import java.util.Map;
导入java.util.List;
导入java.util.ArrayList;
导入com.opencsv.csvreaderheaderware;
导入com.opencsv.exceptions.CsvValidationException;
导入java.io.FileNotFoundException;
导入java.io.FileReader;
导入java.io.IOException;
...
公共静态void main(字符串[]args)引发FileNotFoundException,
IOException,CsvValidationException{
字符串bookFile=“/path/to/titles.csv”;
csvreaderheaderware csvReader=新的csvreaderheaderware(新文件阅读器(bookFile));
List books=new ArrayList();
地图记录;
而((bookRecord=csvReader.readMap())!=null){
书籍。添加(手把簿(bookRecord));
}
}
私人静态书本把手(地图书记录){
author1=新作者(
bookRecord.get(“author1名”),
bookRecord.get(“author1姓氏”)
);
author2=新作者(
bookRecord.get(“author2名”),
bookRecord.get(“author2姓氏”)
);
归还新书(bookRecord.get(“title”)、作者1、作者2);
}
CSV文件中的每一行数据都被读入映射
对象,其中文件头是映射的键(您需要确保文件头是唯一的)。地图对应的值表示CSV文件中的一行数据
唯一的缺点是,您可能需要将字符串值强制转换为其他数据类型—尽管在本例中不是这样,因为数据项已经是字符串。谢谢您的建议。我将检查自定义映射策略是否可以解决我的问题(但我可能会选择
HeaderNameBaseMappingStrategy
,因为列的顺序可以在输入中更改)。但是,如果可能的话,我更愿意使用@CsvRecurse
。但它似乎并没有完成我需要它做的事情:它似乎只适用于同一类类型最多有1个变量的情况,对吗?因此,如果我有1个Author
变量,它将非常有效。但是,有没有一种方法可以将它与我的源bean中的2个Author
变量一起使用呢?
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import com.opencsv.CSVReaderHeaderAware;
import com.opencsv.exceptions.CsvValidationException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
...
public static void main(String[] args) throws FileNotFoundException,
IOException, CsvValidationException {
String bookFile = "/path/to/titles.csv";
CSVReaderHeaderAware csvReader = new CSVReaderHeaderAware(new FileReader(bookFile));
List<Book> books = new ArrayList();
Map<String, String> bookRecord;
while ((bookRecord = csvReader.readMap()) != null) {
books.add(handleBook(bookRecord));
}
}
private static Book handleBook(Map<String, String> bookRecord) {
Author author1 = new Author(
bookRecord.get("author1 given name"),
bookRecord.get("author1 surname")
);
Author author2 = new Author(
bookRecord.get("author2 given name"),
bookRecord.get("author2 surname")
);
return new Book(bookRecord.get("title"), author1, author2);
}