用java中的键对Json响应进行分组 - android studio

Posted

技术标签:

【中文标题】用java中的键对Json响应进行分组 - android studio【英文标题】:Grouping Json response with keys in java - android studio 【发布时间】:2017-01-05 09:04:02 【问题描述】:

我是 java 和 android 开发的新手。我正在学习 json 解析。我得到了类似这样的 json 响应。

"code":"0","data":    
[ "chrDesigName":"Developer","chrempName":"Test Employee1",
  "chrDesigName":"Developer","chrempName":"Test Employee2", 
  "chrDesigName":"Tester","chrempName":"Test Employee3",
  "chrDesigName":"Analyst","chrempName":"Test Employee4",
  "chrDesigName":"Developer","chrempName":"Test Employee5",
  "chrDesigName":"Tester","chrempName":"Test Employee6"]

我想把这个 Json 解析成这样的东西。

"Developer" : ["chrempName" : "Test Employee1",
                    "chrempName" : "Test Employee2",
                    "chrempName" : "Test Employee5"],
"Tester" : ["chrempName" : "Test Employee3",
                    "chrempName" : "Test Employee6"],
"Analyst" : ["chrempName" : "Test Employee4"]  

我怎样才能做到这一点?我的动机是根据他们的指定对所有员工进行分组。

【问题讨论】:

【参考方案1】:

作为一个快速破解,我使用了 2 个不同的库来完成它。您也可以使用 Jackson 来“统一”。

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

public class JsonReformatter 

    public static void main(String[] args) throws Exception 
        String jsonString = "\"code\": \"0\",\"data\": [\"chrDesigName\": \"Developer\",\"chrempName\": \"Test Employee1\",\"chrDesigName\": \"Developer\",\"chrempName\": \"Test Employee2\",\"chrDesigName\": \"Tester\",\"chrempName\": \"Test Employee3\",\"chrDesigName\": \"Analyst\",\"chrempName\": \"Test Employee4\",\"chrDesigName\": \"Developer\",\"chrempName\": \"Test Employee5\",\"chrDesigName\": \"Tester\",\"chrempName\": \"Test Employee6\"]";

        ObjectMapper mapper = new ObjectMapper();

        // Map<String, Object> dataMap = mapper.readValue(jsonString,
        // new TypeReference<Map<String, Object>>() 
        // );
        //
        // System.out.println(dataMap.get("data") +
        // ((ArrayList)dataMap.get("data")).get(0).getClass().getName()) ;

        JsonArray dataArray = new JsonParser().parse(jsonString).getAsJsonObject().getAsJsonArray("data");

        HashMap<String, List<String>> designationsMap = new HashMap<String, List<String>>();

        for (JsonElement element : dataArray) 
            String designation = element.getAsJsonObject().get("chrDesigName").getAsString();
            String empName = element.getAsJsonObject().get("chrempName").getAsString();
            if (designationsMap.containsKey(designation)) 
                designationsMap.get(designation).add(empName);
             else 
                ArrayList<String> emptyList = new ArrayList<String>();
                emptyList.add(empName);
                designationsMap.put(designation, emptyList);
            
        

        StringWriter result = new StringWriter();
        mapper.writeValue(result, designationsMap);
        System.out.println(result);

    


打印出来

"Analyst":["Test Employee4"],"Tester":["Test Employee3","TestEmployee6"],"Developer":["Test Employee1","Test Employee2","Test Employee5"]

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.1</version>
</dependency>

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
</dependency>

【讨论】:

你是如何导入这两个库的?我试过“编译'com.fasterxml.jackson.core:jackson-core:2.7.3'编译'com.fasterxml.jackson.core:jackson-annotations:2.7.3'编译'com.fasterxml.jackson.core:jackson -databind:2.7.3' 在 gradle 中编译 'com.google.code.gson:gson:2.2.4'" 并在库中添加了 "jackson-mapper-lgpl-1.2.1.jar"。出现“错误:无法访问 org.codehaus.jackson.ObjectCodec 的 ObjectCodec 类文件未找到”,无法解析符号 objectmapper 并且无法解析方法 writevalue 添加了我在 Maven 中使用的依赖项。如果您手动添加 jar,可能会很困难,因为在运行时您可能会遇到 ClassNotFound 异常 很好。我现在只得到 mapper.writefile 的未处理异常 你能说出完整的堆栈跟踪和你得到的错误吗?另外,如果答案有效,请务必接受答案:) 错误:(16, 32) 错误: 包 org.codehaus.jackson.map 不存在, 错误:(28, 32) 错误: 包 org.codehaus.jackson.map 不存在,错误:(52, 9) 错误: 找不到符号类 ObjectMapper, 错误:(52, 35) 错误: 找不到符号类 ObjectMapper, 错误:(85, 16) 错误: 找不到符号类 JsonMappingException【参考方案2】:

代码如下:

JsonParser parser =  new JsonParser();

JsonElement jsonElement = parser.parse(json);
JsonObject jsonObj = jsonElement.getAsJsonObject();

JsonArray data = new JsonArray();
data = jsonObj.getAsJsonArray("data");

JsonArray developer = new JsonArray();
JsonArray tester = new JsonArray();
JsonArray analyst = new JsonArray();

for (int i=0; i < data.size; i++)
JsonObject itemArr = (JsonObject)data.get(i);
JsonObject temp = new JsonObject();

if(itemArr.get("chrDesigName").getAsString().equals("Developer"))
   temp.addProperty("chrempName",itemArr.get("chrempName").getAsString());
   developer.add(temp);
else if(itemArr.get("chrDesigName").getAsString().equals("Tester"))
   temp.addProperty("chrempName",itemArr.get("chrempName").getAsString());
   tester.add(temp);
else if(itemArr.get("chrDesigName").getAsString().equals("Analyst"))
   temp.addProperty("chrempName",itemArr.get("chrempName").getAsString());
   analyst.add(temp);



JsonObject resultObject = new JsonObject();
resultObject.add("Developer",developer);
resultObject.add("Tester",tester);
resultObject.add("Analyst",analyst);

这样您就可以根据需要创建一个新的resultObject 对象。这是一种静态方式。您可以将其进一步采用动态方式。您需要添加com.google.gson 库来编译此代码。

【讨论】:

我不知道会有多少名称或所有名称。所以我必须以动态的方式做到这一点。你能帮忙吗?【参考方案3】:

您可以通过以下方式简单地实现此目的:首先将所有 'chrDesigName' 值存储在一个数组中,然后遍历该数组的每个元素以创建所需的 JSON 对象。

e.g. //using JSON.simple module for decode/encode into JSON object.
JSONObject obj1 = "code":"0","data":    
[ "chrDesigName":"Developer","chrempName":"Test Employee1",
  "chrDesigName":"Developer","chrempName":"Test Employee2", 
  "chrDesigName":"Tester","chrempName":"Test Employee3",
  "chrDesigName":"Analyst","chrempName":"Test Employee4",
  "chrDesigName":"Developer","chrempName":"Test Employee5",
  "chrDesigName":"Tester","chrempName":"Test Employee6"];

//Now, store all 'chrDesigName' in a local arrray.
List<String> arr = new ArrayList<String>();
for(JSONObject json : obj1.get("data"))
   //avoid to add duplicate entry. e.g. there are multiple Developer so avoid adding more than 1 times.
   boolean isDuplicate = false; 
   for(int i=0; i<arr.size();i++)        
       if(arr[i]==json.get("chrDesigName"))
           isDuplicate = true;
       
    
    if(isDuplicate==false)
        arr.add(json.get("chrDesigName"));
    


//Now finally create your desired parsed JSON object.
JSONObject result= new JSONObject(); //final Result JSON object.
for(String chrDesigName : arr)
    //first adding empty list.
    result.put(chrDesigName, new ArrayList<JSONObject>());

    //now, checking on each data obj1 if it has chrDesigName and if yes then getting its chrEmpName and adding in list.
    for(JSONObject json : obj1.get("data"))
        if(chrDesigName==json.get("chrDesigName")
            JSONObject sub_json = new JSONObject();
            sub_json.put("chrempName",json.get("chrempName");
            result.get(chrDesigName).add(sub_json);
        
        

【讨论】:

在“result.get(chrDesigName).add(sub_json);”上获取“无法解析方法 add(org.json.JSONObject)”【参考方案4】:

代码如下:

public class TestJSONGroup 
    public static void main(String[] args) throws ParseException 
        
        JSONParser parser = new JSONParser();
        String jsonString = "\"code\":\"0\",\"data\":"
        + "[ \"chrDesigName\":\"Developer\",\"chrempName\":\"Test Employee1\","
        + "  \"chrDesigName\":\"Developer\",\"chrempName\":\"Test Employee2\","
        + "  \"chrDesigName\":\"Tester\",\"chrempName\":\"Test Employee3\","
        + "  \"chrDesigName\":\"Analyst\",\"chrempName\":\"Test Employee4\","
        + "  \"chrDesigName\":\"Developer\",\"chrempName\":\"Test Employee5\","
        + "  \"chrDesigName\":\"Tester\",\"chrempName\":\"Test Employee6\"]";
        
        //JSONObject obj1 =  (JSONObject) parser.parse( jsonString );
        JSONObject obj1 = new JSONObject(jsonString);

        //Now, store all 'chrDesigName' in a local arrray.
        List<String> arr = new ArrayList<String>();
        
        JSONArray json = obj1.getJSONArray("data");
        for (int j = 0; j < json.length(); j++) 
           //avoid to add duplicate entry. e.g. there are multiple Developer so avoid adding more than 1 times.
           boolean isDuplicate = false; 
           String chrDesigName = new String();
           for(int i=0; i<arr.size();i++)
               JSONObject jsonObject1 = json.getJSONObject(j);
               chrDesigName = jsonObject1.optString("chrDesigName"); 
               if(arr.get(i).equalsIgnoreCase(chrDesigName.trim()))
                   isDuplicate = true;
               
            
            if(isDuplicate==false)
                arr.add(chrDesigName);
            
        
        arr.remove(0);

        //Now finally create your desired parsed JSON object.
        JSONObject result= new JSONObject(); //final Result JSON object.
        for(String chrDesigName : arr)
            //first adding empty list.
            result.put(chrDesigName, new ArrayList<JSONObject>());
            //now, checking on each data obj1 if it has chrDesigName and if yes then getting its chrEmpName and adding in list.
            String chrDesigName2 = new String();
            JSONArray array = new JSONArray();
            for (int j = 0; j < json.length(); j++) 
                JSONObject jsonObject1 = json.getJSONObject(j);
                chrDesigName2 = jsonObject1.optString("chrDesigName");
                if(chrDesigName.equalsIgnoreCase(chrDesigName2.trim()))
                    JSONObject sub_json = new JSONObject();
                    sub_json.put("chrempName",json.get(j));
                    array.put(json.get(j));
                
             
            result.put(chrDesigName, array);
        
        System.out.println("result: "+ result.toString());
    

结果会是,只是在其他一些地方修改


   "Analyst": [
      
         "chrDesigName": "Analyst",
         "chrempName": "Test Employee4"
      
   ],
   "Tester": [
      
         "chrDesigName": "Tester",
         "chrempName": "Test Employee3"
      ,
      
         "chrDesigName": "Tester",
         "chrempName": "Test Employee6"
      
   ],
   "Developer": [
      
         "chrDesigName": "Developer",
         "chrempName": "Test Employee1"
      ,
      
         "chrDesigName": "Developer",
         "chrempName": "Test Employee2"
      ,
      
         "chrDesigName": "Developer",
         "chrempName": "Test Employee5"
      
   ]

【讨论】:

以上是关于用java中的键对Json响应进行分组 - android studio的主要内容,如果未能解决你的问题,请参考以下文章

基于多个键对 Json 进行分组

使用字典中的键对对象数组进行排序

如何使用 LINQ 中的键对值从单个字段中获取重复数据?

添加键的值并按在 Python 中的字典列表中出现的键对其进行排序

Python:通过每个国家的Json数据中的键求和的值

从Map的Java流中,通过键对它们进行分组,并找到最大值无法正常工作