我想采取"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""用户名"用户类型";正确地但我不知道如何阅读——;id":[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"中的值添加到"list"中。换句话说,我不能从JSONArray中获取值。
有很多方法可以改进代码,让我们从重新表述问题开始:您需要从JSON字符串到映射了所有属性的模型对象。
有一些很好的库可以做到这一点,比如Jackson和Gson,但它也可以像您正在做的那样使用jsonsimple1.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<JSONObject> users = (List<JSONObject>) root.get("users");
行工作的原因。
现在您已经有了一个列表,可以使用通常的foreach循环for (JSONObject user: users) {...}
迭代元素并处理每个元素。
对于内部";ids";我们可以做同样的事情,但从您的代码来看,id似乎必须是整数,json simple返回Long
对象,所以我们需要转换它们,这就是为什么存在第二个循环(如果模型对象接受List<Long>
,则不需要它(。
做同样事情的另一种方法是使用java8流,指定将源对象转换为目标对象所需的不同步骤:
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);
}
在我看来,流api在需要一步一步地将对象列表从一种类型转换为另一种类型的情况下更清晰,在本例中,它没有太大区别,但在有许多中间步骤的更复杂的情况下,它可能是一个非常有用的工具。