web-dev-qa-db-fra.com

Création d'une chaîne JSON ordonnée à partir de LinkedHashMap

J'avais besoin d'avoir des paires clé/valeur dans l'ordre de mon insertion. J'ai donc choisi d'utiliser LinkedHashMap sur HashMap. Mais je dois convertir la LinkedHashMap en une chaîne JSON dans laquelle l'ordre dans la LinkedHashMap est conservé dans la chaîne.

Mais actuellement, je le réalise en: 

  1. Convertissez d'abord le LinkedHashMap en JSON.
  2. Puis convertir le JSON en une chaîne.

    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());
        }
    }
    

La sortie est:

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

Mais je le veux dans l'ordre d'insertion des clés, comme ceci:

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

Une fois que j'ai converti la LinkedHashMap en un JSON, il perd son ordre (il est évident que JSON n'a pas la notion d'ordre) et la chaîne est donc également en panne. Maintenant, comment générer une chaîne JSON dont l'ordre est identique à celui de la variable LinkedHashMap?

7
Karthic Rao

Gson si votre ami. Ceci imprimera la carte commandée dans une chaîne JSON ordonnée.

J'ai utilisé la dernière version de Gson (2.3.1), vous pouvez le télécharger via les options suivantes au bas de cet article.

import Java.util.LinkedHashMap;
import Java.util.Map;

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"}
    }
}

Options de dépendance

Maven

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

Gradle

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

Ou vous pouvez visiter Maven Central pour plus d'options de téléchargement.

13
Mr. Polywhirl

JSONObject implique l'utilisation de la bibliothèque org.json. Ne fais pas ça c'est un vieux prototype et il y a de meilleures options comme Jackson et GSON. Avec Jackson, vous utiliseriez simplement:

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

et obtenez une chaîne JSON avec des entrées dans l'ordre de passage utilisé par votre carte.

2
StaxMan

Pour trier par ordre alphabétique, voici la bonne façon de procéder avec Jackson 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();
}
0
mtyurt

JSON ne prenant pas l'ordre d'insertion à cause des paramètres linkedhashmap, les deux sont des chaînes. Est-ce bien de changer d'abord param en Integer comme ci-dessous mentionné:

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());
0
Subbu

J'ai rencontré le même problème. Je devais utiliser cette bibliothèque particulière, et le premier élément devait être avec la clé "$ type". Voici ma décision:

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;
    }
}

Comme vous le voyez, je dépasse la méthode entrySet, celle utilisée dans la méthode toString