在Java中将json对象转换为tsv格式

时间:2018-06-22 22:56:42

标签: java json csv object hashmap

我有以下课程

  public String put(final Params parameter) {
    serializedParams = JsonSerializer.serialize(params);
}

为了将其转换为tsv,我使用以下命令将其序列化为json:

  {
      "dataType" : "abc",
      "group" : { },
      "aggregates" : [ ],
      "scene" : [ "AC" ],
      "company" : [ "pr" ],
      "fit" : [ {
        "prod" : [ "A1" ]
      } ],
      "params" : null,
      "tempo" : "note",
      "id" : "123",
      "valuation" : USD
    }

所以我得到这样的输出:

parameter.getGroup.values()

我最终的输出是这样的(制表符分隔):

abc AC pr prod A1 note 123 USD

我尝试使用:

{{1}}

但是,这仅给出了以[val]这样的格式显示的值。

如何同时获取对象的所有值?是否可以同时从地图,列表等获取值而无需单独处理?

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

从您的问题中尚不清楚,在某些情况下生成选项卡式输出时,您想如何处理数据,但是我将尝试提供一些示例代码来帮助您。

但是,首先,我想说序列化为JSON,然后序列化JSON以制表符分隔的值不是一个好主意。当您可能要执行一个步骤时,您需要执行两个步骤,JSON序列化并不能使您更接近目标,并且序列化通常是一个代价高昂的过程-您不想做得比做的更多。 / p>

因此,请记住以下示例,以示例说明如何实现简单的制表符分隔的序列化:

由于您的Params类内部有至少一个要处理的自定义对象(指List对象的Aggregate),我建议创建一个接口,您的类可以指示它们能够序列化为制表符分隔的字符串的工具。

我仅将此接口称为TabSerializable

public interface TabSerializable {
    public String toTabbedString();
}

接下来,我修改了Params类以实现此接口:

public class Params implements TabSerializable{
    //fields omitted for brevity.
    ...

    public String toTabbedString(){
        StringJoiner joiner = new StringJoiner("\t");

        TabSerializer.addValue(dataType, joiner);
        TabSerializer.addValue(group, joiner);
        TabSerializer.addValue(aggregates, joiner);
        TabSerializer.addValue(scene, joiner);
        TabSerializer.addValue(company, joiner);
        TabSerializer.addValue(fit, joiner);
        TabSerializer.addValue(params, joiner);
        TabSerializer.addValue(tempo, joiner);
        TabSerializer.addValue(id, joiner);
        TabSerializer.addValue(valuation, joiner);

        return joiner.toString();
    }
    ...
}

我还创建了一个示例Aggregate类,该类也实现了此接口:

public class Aggregate implements TabSerializable{
    private String data;

    @Override
    public String toTabbedString() {
        return data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

由于您拥有大多数通用类型的数据结构,例如地图和列表,因此我创建了TabSerializer类来帮助将这些结构转换为制表符分隔的字符串:

import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

public class TabSerializer {
    private static void addValuesFromMap(Map<?,?> obj, StringJoiner joiner) {
        for(Object key: obj.keySet()){
            Object value = obj.get(key);
            if(value == null){
                continue;
            }
            addValue(key, joiner);
            addValue(value, joiner);
        }
    }

    private static void addValuesFromList(List<?> arr, StringJoiner joiner) {
        for(int i=0; i<arr.size(); i++){
            Object value = arr.get(i);
            addValue(value, joiner);            
        }
    }

    public static void addValue(Object value, StringJoiner joiner){
        if(value == null){
            return;
        }
        if(value instanceof List){
            addValuesFromList((List<?>)value, joiner);
        }else if(value instanceof Map){
            addValuesFromMap((Map<?,?>)value, joiner);
        }else if(value instanceof TabSerializable){
            joiner.add(((TabSerializable) value).toTabbedString());
        }else{
            joiner.add(String.valueOf(value));

        }
    }
}

基于您在问题中给出的示例,我编写了上面的逻辑以跳过空值和顶级字段(Params类中的字段)的名称。

最后,我创建了一个带有main的类,以测试上述逻辑:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainTabDelim {

    public static void main(String[] args) {
        Params params = new Params();
        params.setDataType("abc");
        List<String> scene = new ArrayList<>();
        scene.add("AC");
        params.setScene(scene);
        List<String> company = new ArrayList<>();
        company.add("pr");
        params.setCompany(company);
        List<Map<String, List<String>>> fit = new ArrayList<>();
        List<String> fitInner = new ArrayList<>();
        fitInner.add("A1");
        Map<String, List<String>> fitMap = new HashMap<>();
        fitMap.put("prod", fitInner);
        fit.add(fitMap);
        params.setFit(fit);
        params.setTempo("note");
        params.setId("123");
        params.setValuation("USD");

//      Uncomment the following lines to see how Aggregate works:
//      List<Aggregate> aggregates = new ArrayList<>();
//      Aggregate ag = new Aggregate();
//      ag.setData("some_data");
//      aggregates.add(ag);
//      params.setAggregates(aggregates);

        System.out.println(params.toTabbedString());
    }
}

输出为:

  

abc AC pr prod A1 note 123 USD

我希望这可以帮助您入门。享受吧!