Java 从 LinkedHashMap 构建有序的 JSON 字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29491281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:05:29  来源:igfitidea点击:

Building ordered JSON String from LinkedHashMap

javajsonstringhashmaplinkedhashmap

提问by Karthic Rao

I had a need for having Key/Value pairs in the order of my insertion, so I opted to use LinkedHashMapover HashMap. But I need to convert the LinkedHashMapinto a JSON String where the order in the LinkedHashMapis maintained in the string.

我需要按插入顺序排列键/值对,所以我选择使用LinkedHashMapover HashMap. 但我需要将 转换LinkedHashMap为 JSON 字符串,其中的顺序在字符串中LinkedHashMap维护。

But currently I'm achieving it by:

但目前我正在通过以下方式实现它:

  1. First converting the LinkedHashMap into JSON.
  2. Then converting the JSON into a string.

    import java.util.LinkedHashMap;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    public class cdf {
        public static void main(String[] args) {
            Map<String,String > myLinkedHashMap =  new LinkedHashMap<String, String>();
            myLinkedHashMap.put("1","first");
            myLinkedHashMap.put("2","second");
            myLinkedHashMap.put("3","third");
    
            JSONObject json = new JSONObject(myLinkedHashMap);
            System.out.println(json.toString());
        }
    }
    
  1. 首先将 LinkedHashMap 转换为 JSON。
  2. 然后将 JSON 转换为字符串。

    import java.util.LinkedHashMap;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    public class cdf {
        public static void main(String[] args) {
            Map<String,String > myLinkedHashMap =  new LinkedHashMap<String, String>();
            myLinkedHashMap.put("1","first");
            myLinkedHashMap.put("2","second");
            myLinkedHashMap.put("3","third");
    
            JSONObject json = new JSONObject(myLinkedHashMap);
            System.out.println(json.toString());
        }
    }
    

The output is:

输出是:

{"3":"third","2":"second","1":"first"} . 

But I want it in the order of insertion of the keys, like this:

但我希望它按插入键的顺序排列,如下所示:

{"1":"first","2":"second","3":"third"}

Once I convert the LinkedHashMapinto a JSON it loses it order (it's obvious that JSON doesn't have the notion of order) and hence the string too is out of order. Now, how do I generate a JSON string whose order is same as the LinkedHashMap?

一旦我将LinkedHashMap它转换为 JSON,它就会失去它的顺序(很明显 JSON 没有顺序的概念),因此字符串也是乱序的。现在,我如何生成一个 JSON 字符串,其顺序与LinkedHashMap?

采纳答案by Mr. Polywhirl

Gsonif your friend. This will print the ordered map into an ordered JSON string.

如果你的朋友,Gson。这会将有序映射打印为有序的 JSON 字符串。

If you want to preserve insertion order, use a LinkedHashMap.

如果要保留插入顺序,请使用LinkedHashMap.

I used the latest version of Gson (2.8.5), you can can download it via the following options at the bottom of this post.

我使用的是最新版本的Gson(2.8.5),您可以通过本文底部的以下选项进行下载。

import java.util.*;
import com.google.gson.Gson;

public class OrderedJson {
    public static void main(String[] args) {
        // Create a new ordered map.
        Map<String,String> myLinkedHashMap = new LinkedHashMap<String, String>();

        // Add items, in-order, to the map.
        myLinkedHashMap.put("1", "first");
        myLinkedHashMap.put("2", "second");
        myLinkedHashMap.put("3", "third");

        // Instantiate a new Gson instance.
        Gson gson = new Gson();

        // Convert the ordered map into an ordered string.
        String json = gson.toJson(myLinkedHashMap, LinkedHashMap.class);

        // Print ordered string.
        System.out.println(json); // {"1":"first","2":"second","3":"third"}
    }
}

If you want the items to always be inserted at the right place, use a TreeMapinstead.

如果您希望项目始终插入正确的位置,请改用 a TreeMap

import java.util.*;
import com.google.gson.Gson;

public class OrderedJson {
    public static void main(String[] args) {
        // Create a new ordered map.
        Map<String,String> myTreeHashMap = new TreeMap<String, String>();

        // Add items, in any order, to the map.
        myTreeHashMap.put("3", "third");
        myTreeHashMap.put("1", "first");
        myTreeHashMap.put("2", "second");

        // Instantiate a new Gson instance.
        Gson gson = new Gson();

        // Convert the ordered map into an ordered string.
        String json = gson.toJson(myTreeHashMap, TreeMap.class);

        // Print ordered string.
        System.out.println(json); // {"1":"first","2":"second","3":"third"}
    }
}

Dependency Options

依赖选项

Maven

马文

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

Gradle

摇篮

compile 'com.google.code.gson:gson:2.8.5'

Or you can visit Maven Centralfor more download options.

或者您可以访问Maven Central以获取更多下载选项。

回答by Angad Tiwari

Create JsonArray for Ordered Pair...

为有序对创建 JsonArray...

JSONArray orderedJson=new JSONArray();
Iterator iterator= ;
    while (iterator.hasNext()) {
        Map.Entry me = (Map.Entry)iteratornext();
        System.out.print(me.getKey() + ": ");
        System.out.println(me.getValue());
        JSONObject tmpJson=new JSONObject ();
        tmpJson.put(me.getKey(),me.getValue());//add key/value to tmpjson
        orderedJson.add(tmpJson);//add tmpjson to orderedJson
    }

回答by Subbu

JSON not taking insertion order due to linkedhashmap params both are string. Is it fine to change first param as Integer like below mentioned code:

由于 Linkedhashmap 参数,JSON 不采用插入顺序,两者都是字符串。像下面提到的代码一样将第一个参数更改为整数是否可以:

Map<Integer,String > myLinkedHashMap =  new LinkedHashMap<>();
            myLinkedHashMap.put(1,"first");
            myLinkedHashMap.put(2,"second");
            myLinkedHashMap.put(3,"third");

            System.out.println(myLinkedHashMap);
            JSONObject json = new JSONObject(myLinkedHashMap);
            System.out.println(json.toString());

回答by mtyurt

To sort alphabetically, here is the proper way with Hymanson 2.*:

要按字母顺序排序,以下是 Hymanson 2.* 的正确方法:

Map<String, String> myLinkedHashMap = new LinkedHashMap<String, String>();
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

try {
    System.out.println(mapper.writeValueAsString(myLinkedHashMap));
    //prints {"1":"first","2":"second","3":"third"}
} catch (JsonProcessingException e) {
    e.printStackTrace();
}

回答by StaxMan

JSONObjectimplies use of org.jsonlibrary. Don't do that; it is old prototype and there are better options like Hymanson and GSON. With Hymanson you would just use:

JSONObject暗示使用org.json图书馆。不要那样做;它是旧原型,有更好的选择,如 Hymanson 和 GSON。对于Hyman逊,您只需使用:

String json = new ObjectMapper().writeValueAsString(myLinkedHashMap);

and get JSON string with entries in whatever traversal order your Map uses.

并以您的 Map 使用的任何遍历顺序获取包含条目的 JSON 字符串。

回答by Кирилл Герасимов

I ran into the same problem. I had to use this particular library, and the first element must be with the key "$type". Here is my decision:

我遇到了同样的问题。我必须使用这个特定的库,并且第一个元素必须使用键“$type”。这是我的决定:

import org.json.JSONObject;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;


class TypedJSONObject extends JSONObject {

    private static final String KEY = "$type";

    @Override
    public Set<Map.Entry<String, Object>> entrySet() {
        Set<Map.Entry<String, Object>> superSet = super.entrySet();
        Set<Map.Entry<String, Object>> returnSet = new LinkedHashSet<>();

        HashMap<String, Object> map = new HashMap<>();
        for (Map.Entry<String, Object> entry : superSet) {
            if (entry.getKey().equals(KEY)) {
                map.put(KEY, entry.getValue());
                break;
            }
        }
        Set<Map.Entry<String, Object>> entries = map.entrySet();

        returnSet.addAll(entries);
        returnSet.addAll(superSet);

        return returnSet;
    }
}

As you see I overrite method entrySet, that used in method toString

如您所见,我覆盖了方法 entrySet,该方法在 toString 方法中使用