【问题标题】:How can I read int values from json file in Java?如何从 Java 中的 json 文件中读取 int 值?
【发布时间】:2021-03-28 15:10:36
【问题描述】:

我想获取“ids”并将其分配给一个数组列表。 config.json 文件在这里:


{

  "users":[
  {"user id":1,"user name":"A","user type":"bot1", "ids": [1 ,2]},
  {"user id":2,"user name":"B","user type":"bot2","ids": [1 ,2]},
  {"user id":3,"user name":"C","user type":"bot3","ids": [2 ,3]}
  ]
}

要读取这个 json 文件,我已经尝试过:

JSONArray jsonArrayForUsers = (JSONArray) jsonObject.get("users");
            
            for (int i=0; i<jsonArrayForUsers.size(); i++) { 
                JSONObject obj2 = (JSONObject) jsonArrayForUsers.get(i); 
                long userId = (long) obj2.get("user id"); 
                String userName = (String) obj2.get("user name");
                String userType = (String) obj2.get("user type");
                JSONArray jsonDatasetIds = (JSONArray) jsonObject.get("ids");
                 List <Integer> list =  Arrays.asList(jsonDatasetIds);// Trying to covert JSONArray into an array but error occurs
 
//Type mismatch: cannot convert from List<JSONArray> to List<Integer>
                
                
                users.add(new User((int)userId, userName, userType,list));
            }

我可以正确读取“用户 ID”、“用户名”、“用户类型”。但我不知道如何阅读 -"ids": [1 ,2]- 部分并从中创建一个数组列表。

编辑: 修改后问题解决了

               //It should've been 'obj2.get()'
               JSONArray  jsonDatasetIds = (JSONArray) obj2.get("ids");

               
               for(int a = 0; i<jsonDatasetIds.size();i++){
                   
                   list.add((int)jsonDatasetIds.get(a));
               }
               users.add(new User((int)userId, userName, userType,list));

但现在我无法将“jsonDatasetIds”中的值添加到“列表”。 换句话说,我不能从 JSONArray 中获取值。

【问题讨论】:

  • 在您发布的 JSON 示例中,密钥是“ids”,而在 java 部分中,您正在读取密钥“数据集 ids”。尝试阅读 jsonObject.get("ids")。您也不能通过这种方式将 JSONArray 转换为 List ,您调用 Arrays.asList 所做的只是将对象 JSONArray 包装到一个新列表中。您使用哪个库来解析和读取 JSON?
  • 我正在使用这个“org.json.simple.parser.JSONParser”我也更正了“ids”部分@DanielCamarda
  • 不确定该库,但 JSONArray 很可能是某种可迭代的,如果是这种情况,您可以直接遍历元素。
  • 实际上,通过谷歌搜索,这里有一篇文章展示了如何使用 json-simple 迭代 JSONArray mkyong.com/java/json-simple-example-read-and-write-json 我的建议是使用更完整的库,如 Jackson 或 Gson,它也支持直接编组和解组自定义对象,因此您可以直接将 java bean 映射到 JSON 实体。
  • 谢谢,我试试看

标签: arrays json type-conversion


【解决方案1】:

有很多方法可以改进代码,让我们从重新表述问题开始:您需要从 JSON 字符串转为具有所有属性映射的模型对象。

有很好的库可以做到这一点,例如 JacksonGson,但也可以使用 json-simple 1.1.1 来完成。

假设您的模型对象如下所示:

public class User {
    private int id;
    private String name;
    private String type;
    private List<Integer> ids;

    // and constructor + getters + setters
}

从您提供的 JSON 开始:

{
  "users":[
    {"user id":1, "user name":"A", "user type":"bot1", "ids":[1, 2]},
    {"user id":2, "user name":"B", "user type":"bot2", "ids":[1, 2]},
    {"user id":3, "user name":"C", "user type":"bot3", "ids":[2, 3]}
  ]
}

我们可以进行第一次尝试,如下所示:

public static void main(String[] args) throws ParseException {
    String json =
            "{  \"users\":[" +
            "  {\"user id\":1,\"user name\":\"A\",\"user type\":\"bot1\", \"ids\": [1 ,2]}," +
            "  {\"user id\":2,\"user name\":\"B\",\"user type\":\"bot2\",\"ids\": [1 ,2]}," +
            "  {\"user id\":3,\"user name\":\"C\",\"user type\":\"bot3\",\"ids\": [2 ,3]}" +
            "  ]" +
            "}";
            
    List<User> result = new ArrayList<>();

    JSONParser parser = new JSONParser();
    JSONObject root = (JSONObject) parser.parse(json);
    List<JSONObject> users = (List<JSONObject>) root.get("users");

    for (JSONObject user: users) {
        List<Integer> userIds = new ArrayList<>();
        for (Long id : (List<Long>) user.get("ids")) {
            userIds.add(id.intValue());
        }

        result.add(new User(((Long)user.get("user id")).intValue(), (String) user.get("user name"), (String) user.get("user type"), userIds));
    }

    System.out.println(result);
}

如您所见,JSONArray 可以直接转换为 List,如果我们查看 JSONArray 类的签名,我们就可以理解为什么:

public class JSONArray extends ArrayList implements List, JSONAware, JSONStreamAware

JSONArray 实际上是对 ArrayList 的扩展,因此您不需要创建一个新的,这就是 List&lt;JSONObject&gt; users = (List&lt;JSONObject&gt;) root.get("users"); 行有效的原因。

现在您有了一个列表,可以使用通常的 foreach 循环 for (JSONObject user: users) {...} 遍历元素并处理每个元素。

对于内部“ids”,我们可以做同样的事情,但从您的代码看来,ids 必须是整数,并且 json-simple 返回 Long 对象,所以我们需要转换它们,这就是为什么第二个循环是那里(如果模型对象接受List&lt;Long&gt;,则不需要)。

做同样事情的另一种方法是使用 java 8 流,指定将源对象转换为目标对象所需的不同步骤:

public static void main(String[] args) throws ParseException {
    String json =
            "{  \"users\":[" +
            "  {\"user id\":1,\"user name\":\"A\",\"user type\":\"bot1\", \"ids\": [1 ,2]}," +
            "  {\"user id\":2,\"user name\":\"B\",\"user type\":\"bot2\",\"ids\": [1 ,2]}," +
            "  {\"user id\":3,\"user name\":\"C\",\"user type\":\"bot3\",\"ids\": [2 ,3]}" +
            "  ]" +
            "}";
    
    JSONParser parser = new JSONParser();
    JSONObject root = (JSONObject) parser.parse(json);
    
    List<User> result = ((List<JSONObject>)root.get("users"))
            .stream()
            .map(user -> new User(
                ((Long)user.get("user id")).intValue(),
                (String) user.get("user name"),
                (String) user.get("user type"),
                ((List<Long>) user.get("ids"))
                        .stream()
                        .map(Long::intValue)
                        .collect(Collectors.toList())))
            .collect(Collectors.toList());


    System.out.println(result);
}

在我看来,stream api 在您需要逐步将对象列表从一种类型转换为另一种类型的情况下更为清晰,在此示例中它并没有太大区别,但在更复杂的情况下通过许多中间步骤,它可能是一个非常有用的工具。

【讨论】:

    猜你喜欢
    • 2018-03-15
    • 2023-03-26
    • 2017-09-06
    • 1970-01-01
    • 2011-06-03
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    相关资源
    最近更新 更多