可以編寫一個單元處理器,將每列收集到一張地圖中。例如,以下處理器允許您指定要添加到的鍵和地圖。
package org.supercsv.example;
import java.util.Map;
import org.supercsv.cellprocessor.CellProcessorAdaptor;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.util.CsvContext;
public class MapCollector extends CellProcessorAdaptor {
private String key;
private Map<String, String> map;
public MapCollector(String key, Map<String, String> map){
this.key = key;
this.map = map;
}
public MapCollector(String key, Map<String, String> map,
CellProcessor next){
super(next);
this.key = key;
this.map = map;
}
public Object execute(Object value, CsvContext context) {
validateInputNotNull(value, context);
map.put(key, String.valueOf(value));
return next.execute(map, context);
}
}
然後假設你的產品bean擁有Map<String,String>
類型的字段name
,你可以按如下方式使用處理器。
package org.supercsv.example;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
public class MapCollectorTest extends TestCase {
private static final String CSV = "John,L,Smith\n" +
"Sally,P,Jones";
public void testMapCollector() throws IOException{
ICsvBeanReader reader = new CsvBeanReader(
new StringReader(CSV),
CsvPreference.STANDARD_PREFERENCE);
// only need to map the field once, so use nulls
String[] nameMapping = new String[]{"name", null, null};
// create processors for each row (otherwise every bean
// will contain the same map!)
Product product;
while ((product = reader.read(Product.class,
nameMapping, createProcessors())) != null){
System.out.println(product.getName());
}
}
private static CellProcessor[] createProcessors() {
Map<String, String> nameMap = new HashMap<String, String>();
final CellProcessor[] processors = new CellProcessor[]{
new MapCollector("name1", nameMap),
new MapCollector("name2", nameMap),
new MapCollector("name3", nameMap)};
return processors;
}
}
此輸出:
{name3=Smith, name2=L, name1=John}
{name3=Jones, name2=P, name1=Sally}
你會發現,雖然處理器上的所有3列執行,它只是(在nameMapping陣列因此空值)映射到bean一次。
我還創建了處理器,每個一行讀取時間,否則每個bean將使用同一張地圖......這可能不是你想要的東西;)
謝謝您的回答, 我會試一試,雖然我的第一印象是爲每一行創建單元處理器將顯着降低性能..我有一些CSV超過10000行... –
你認爲這將是確定的,如果CsvContext也暴露了這一行迄今爲止已處理的內容以及當前標題值的名稱。在這種情況下,我可以像這樣創建一個CsvProcessor: 'if(csvContext.getLineSoFar(csvContext.getCurrentHeader())!= null){csvContext.getLineSoFar()。put(STRING,STRING); } else { new HashMap(); } ' –