json 为什么Iterator突然以相反的顺序打印Map元素?

7xzttuei  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(115)

假设我们有一个JAVA代码块,它正在遍历JSON文件。

*JAVAFile

// getting phoneNumbers
        JSONArray ja = (JSONArray) jo.get("phoneNumbers");//jo is the JSONObject of the given JSON 
        //Iterating through phonenumbers 
        Iterator itr2 = ja.iterator();
          
        while (itr2.hasNext()) 
        {
            Iterator<Map.Entry>itr1 = ((Map)itr2.next()).entrySet().iterator();
            while (itr1.hasNext()) {
                Map.Entry pair = itr1.next();
                System.out.println(pair.getKey() + " : " + pair.getValue());
            }
        }
    • JSONfile**
{
    "firstName": "Souvik",
    "lastName": "Dey",
    "address": {
        "streetAddress": "D P Rd",
        "city": "Barasat",
        "state": "WB",
        "postalCode": 700126
    },
    "age": 23,
    "phoneNumbers": [
        {
            "type": "personal",
            "number": "#######23"
        },
        {
            "type": "office",
            "number": "########"
        }
    ]
}
    • 问题**

为什么我得到这个:

    • 输出**

编号:##23
类型:个人
编号:#######
类型:办公室

    • 期望**

类型:个人
编号:######23
类型:办公室
编号:########

hjzp0vay

hjzp0vay1#

JSON中的Map元素不被视为有序数据。它以不同的顺序出现,原因类似于HashMap内容的顺序。您不应该期望HashMap按照您将内容放入其中的相同顺序迭代,对于来自JSON源的Map内容也是如此。
如果你想在JSON中保留Map数据的顺序,那么你应该将Map数据转换为数组并存储在JSON中。

n3ipq98p

n3ipq98p2#

您可以使用Jackson将JSON文件解析为JsonNode,获取phoneNumbers字段并遍历节点。Jackson在引擎盖下使用了一个LinkedHashMap,所以他们的密钥的原始顺序应该被保留。

import java.io.*;
import java.util.Iterator;
import java.util.Map.Entry;
import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.*;

public class JsonReaderExample {
    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) {
        try {
            ClassLoader classLoader = JsonReaderExample.class.getClassLoader();
            InputStream inputStream = classLoader.getResourceAsStream("input.json");
            JsonNode person = objectMapper.readTree(inputStream);
            JsonNode phoneNumbers = person.get("phoneNumbers");
            if (phoneNumbers.isArray()) {
                for (final JsonNode phoneNumber : phoneNumbers) {
                    Iterator<Entry<String, JsonNode>> it = phoneNumber.fields();
                    while (it.hasNext()) {
                        Entry<String, JsonNode> entry = it.next();
                        System.out.printf("%s: %s%n", entry.getKey(), entry.getValue());
                    }
                }
            }
        } catch (StreamReadException e) {
            e.printStackTrace();
        } catch (DatabindException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

最安全的办法是将JSON反序列化为POJO。您可以使用Jackson读取JSON数据并将其解析为Person

import java.io.*;
import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.*;

public class JsonReaderExample {
    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) {
        try {
            ClassLoader classLoader = JsonReaderExample.class.getClassLoader();
            InputStream inputStream = classLoader.getResourceAsStream("input.json");
            Person person = objectMapper.readValue(inputStream, Person.class);

            for (PhoneNumber phoneNumber : person.phoneNumbers) {
                System.out.printf("type: %s%n", phoneNumber.type);
                System.out.printf("number: %s%n", phoneNumber.number);
            }
        } catch (StreamReadException e) {
            e.printStackTrace();
        } catch (DatabindException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class Person {
        public String firstName;
        public String lastName;
        public Address address;
        public int age;
        public PhoneNumber[] phoneNumbers;
    }

    private static class PhoneNumber {
        public String type;
        public String number;
    }

    private static class Address {
        public String streetAddress;
        public String city;
        public String state;
        public int postalCode;
    }
}

输出:

type: personal
number: #######23
type: office
number: ########

相关问题