0

我有一个简单的 POJO,里面有一个 Map。

public class Product {
    public Map map;
}

然后我的 csv 看起来像这样:

"mapEntry1","mapEntry2","mapEntry3"

所以我创建了一个自定义单元处理器来解析这些:

 public class MapEntryCellProcessor {
     public Object execute(Object val, CsvContext context) {
         return next.execute(new AbstractMap.SimpleEntry<>("somekey", val), context);
     }
 }

然后我在我的产品中添加一个条目设置器方法:

public void setName(Entry<String, String> entry) {
    if (getName() == null) {
        name = new HashMap<>();
    }
    name.put(entry.getKey(), entry.getValue());
}

不幸的是,这意味着我有 2 个 setter 方法:一个接受地图,另一个接受对我不起作用的条目(我无法控制 POJO 的生成方式)。有没有其他方法可以解析这样的 CSV 并且只有在我的产品中接受 Map 的设置器?

4

1 回答 1

1

可以编写一个单元处理器,将每一列收集到一个地图中。例如,以下处理器允许您指定要添加的键和映射。

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

}

然后假设您的 Product bean 有一个nametype字段Map<String,String>,您可以按如下方式使用处理器。

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 列上执行,但它只映射到 bean 一次(因此 nameMapping 数组中的空值)。

每次读取一行时,我还创建了处理器,否则每个 bean 都将使用相同的映射......这可能不是你想要的;)

于 2014-04-08T10:01:14.363 回答