Testen von zwei JSON-Objekten auf Gleichheit ohne Berücksichtigung der untergeordneten Reihenfolge in Java


233

Ich suche nach einer JSON-Analysebibliothek, die das Vergleichen von zwei JSON-Objekten unterstützt, bei denen die untergeordnete Reihenfolge ignoriert wird, insbesondere zum Testen von JSON-Einheiten, die von einem Webdienst zurückkehren.

Unterstützt eine der wichtigsten JSON-Bibliotheken dies? Die org.json-Bibliothek führt einfach einen Referenzvergleich durch.


1
Können nicht beide Objekte zur Zeichenfolgendarstellung serialisiert und verglichen werden? Ich denke, alle Bibliotheken unterstützen toString()das Konvertieren des Objekts in einen JSONString.
Teja Kantamneni

47
Dies setzt voraus, dass die Reihenfolge bei der Serialisierung zu und von Zeichenfolgen immer gleich ist. Ich fühle mich nicht wohl, wenn ich diese Annahme mache.
Jeff

Du hast recht, Jeff, es ist überhaupt nicht sicher. Dieser Test zeigt ein Szenario, in dem die Zuordnungen identisch sind, toString () jedoch nicht dieselbe Ausgabe zurückgibt : gist.github.com/anonymous/5974797 . Dies liegt daran, dass die zugrunde liegende HashMap wachsen kann. Wenn Sie Schlüssel entfernen, wird das interne HashMap-Array nicht verkleinert.
Guillaume Perrot

Antworten:


84

Als allgemeiner architektonischer Punkt rate ich normalerweise davon ab, Abhängigkeiten von einem bestimmten Serialisierungsformat über Ihre Speicher- / Netzwerkschicht hinaus ausbluten zu lassen. Daher würde ich zunächst empfehlen, die Gleichheit zwischen Ihren eigenen Anwendungsobjekten und nicht deren JSON-Manifestationen zu testen.

Trotzdem bin ich derzeit ein großer Fan von Jackson, was meine schnelle Lektüre der ObjectNode.equals () -Implementierung nahe legt, dass der von Ihnen gewünschte Vergleich der festgelegten Mitgliedschaft durchgeführt wird:

public boolean equals(Object o)
{
    if (o == this) return true;
    if (o == null) return false;
    if (o.getClass() != getClass()) {
        return false;
    }
    ObjectNode other = (ObjectNode) o;
    if (other.size() != size()) {
        return false;
    }
    if (_children != null) {
        for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
            String key = en.getKey();
            JsonNode value = en.getValue();

            JsonNode otherValue = other.get(key);

            if (otherValue == null || !otherValue.equals(value)) {
                return false;
            }
        }
    }
    return true;
}

Diese Methode ist nicht symmetrisch, da sie nur die Teilmengenbeziehung der Kinder testet, nicht die Gleichheit. Das 'andere' Objekt hat möglicherweise mehr Kinder als in _children, und diese Methode würde immer noch true zurückgeben.
Yoni

23
@ Yoni: Nicht wahr, da es einen Größenvergleich gibt. Sie müssen genau die gleiche Anzahl von Kindern sowie die gleichen Kinder haben. @Jolly Roger: In diesem Fall serialisiere ich das Objekt nicht von JSON zurück in ein POJO, aber wenn ich JSON ein System sende, das dies tut, kann ich mich nicht darauf verlassen, dass es in genau demselben Format zurückgesendet wird, in dem ich es gesendet habe es.
Jeff

1
@ Jeff Hat das bei dir funktioniert? Im Juni schlägt assertEquals für mich fehl. Das Projekt verwendet eine alte Version (1.5), fyi.
Ronnyfm

1
Ich denke, Sie vermissen einige Tests auf hoher Ebene, wenn Sie JSON nicht behaupten. Sie könnten einen Thin-Test durchführen, der eine http-Anfrage stellt und mit einem erwarteten JSON antwortet - dies ist das Hauptfunktionsverhalten des Webdienstes.
Mogronalol

Nur ein kleiner Hinweis zur Leistung: Der Code, der 'value' mit 'otherValue' vergleicht, kann vereinfacht werden, wenn (value.equals (other.get (key)) false zurückgibt, da 'value' garantiert nicht null und ist Die equals () -Methode von JsonNode sollte ein Nullargument akzeptieren
Tillmann,

154

Probieren Sie JSONAssert von Skyscreamer aus .

Sein nicht strenger Modus hat zwei Hauptvorteile, die ihn weniger spröde machen:

  • Objekterweiterbarkeit (z. B. mit einem erwarteten Wert von {id: 1} würde dies immer noch passieren: {id: 1, moredata: 'x'} .)
  • Lose Array-Reihenfolge (zB ['Hund', 'Katze'] == ['Katze', 'Hund'])

Im strengen Modus verhält es sich eher wie die Testklasse von json-lib.

Ein Test sieht ungefähr so ​​aus:

@Test
public void testGetFriends() {
    JSONObject data = getRESTData("/friends/367.json");
    String expected = "{friends:[{id:123,name:\"Corby Page\"}"
        + ",{id:456,name:\"Solomon Duskis\"}]}";
    JSONAssert.assertEquals(expected, data, false);
}

Die Parameter im Aufruf von JSONAssert.assertEquals () sind erwartetJSONString , actualDataString und isStrict .

Die Ergebnismeldungen sind ziemlich klar, was beim Vergleich wirklich großer JSON-Objekte wichtig ist.


18
Ich habe diese Lösung verwendet, aber ich habe gerade festgestellt, dass Sie auch einen JSONCompareMode Ihrer Wahl bereitstellen können. Eines davon ist NON_EXTENSIBLE. Sie hätten also JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);ungefähr Folgendes : Der Modus NON_EXTENSIBLE bedeutet, dass neue oder fehlende Felder Fehler verursachen, die Reihenfolge jedoch nicht. Die Verwendung von false würde einen milden Modus auslösen, der keine zusätzlichen oder fehlenden untergeordneten Elemente meldet.
Dan Temple

1
Der Vergleichsmodus NON_EXTENSIBLE ist genau das , wonach ich gesucht habe. Danke dafür, Dan.
ThoughtCrhyme

Bevor ich ganz aufgeregt bin: Unterstützt dies auch verschachtelte JSON-Objekte und -Arrays? :)
Christian

2
Möglicherweise möchten Benutzer dieses JSONassert-Problem berücksichtigen, bevor sie die Bibliothek verwenden. Dies weist darauf hin, dass derzeit potenzielle Lizenzprobleme mit einer Abhängigkeit von der Bibliothek vorliegen .
Chriki

3
JSONAssert-Problem Nr. 44 wurde durch den Austausch der Reinraumbibliothek in PR 67 behoben, das heute als JSONAssert 1.4.0 veröffentlicht wurde.
Carter Seite

49

Verwenden von GSON

JsonParser parser = new JsonParser();
JsonElement o1 = parser.parse("{a : {a : 2}, b : 2}");
JsonElement o2 = parser.parse("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

Bearbeiten: Seit GSON v2.8.6 ist die Instanzmethode JsonParser.parseveraltet. Sie müssen die statische Methode verwenden JsonParser.parseString:

JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

Funktioniert in GSON 2.8.2 für mich.
Tom Saleeba

1
Es funktioniert nicht, wenn die jsonArray-Elemente nicht in Ordnung sind. Version 2.8.2
Naveen Kumar RB

1
Funktioniert nicht für mich, wenn die Reihenfolge der Objekte / Elemente unterschiedlich ist
Jknair

Es hat bei mir funktioniert, weil ich es nur für einen Unit-Test haben wollte, bei dem die beiden jsons-Eigenschaften dieselbe Reihenfolge hatten
GabrielBB

@GabrielBB Sie sollten die Frage bearbeiten und angeben, in welcher Version die API veraltet ist und in welcher Version der neue Codestil funktioniert.
klares Licht

30

Ich würde folgendes tun:

JSONObject obj1 = /*json*/;
JSONObject obj2 = /*json*/;

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(obj1.toString());
JsonNode tree2 = mapper.readTree(obj2.toString());

return tree1.equals(tree2);

Wenn Sie Jackson bereits verwenden, ist dies meiner Meinung nach die beste Antwort.
Christoph Dietze

18
Aber das ist ein strenger Vergleich, denke ich. Es wird false für zwei gleiche json mit unterschiedlicher Reihenfolge der Elemente zurückgegeben.
Deadpool

@deadpool das Prinzip ist solide, Sie müssten nur den Vergleich ändern, um mehr involviert zu sein (z. B. nach Schlüsselfeldern suchen und nicht nach einfachen Bäumen).
Jwenting

Dies ist die beste Antwort aller Zeiten. Es beantwortet jetzt nicht nur meine Frage, sondern auch fast jeden Objektvergleich, den wir durchführen müssen. Danke, Joshu.
Luiz Feijão Veronesi

2
@deadpool, es war vielleicht ein strenger Vergleich, aber jetzt ist es nicht streng.
Andrei Damian-Fekete

18

Sie können versuchen, die JSONAssert- Klasse von json-lib zu verwenden :

JSONAssert.assertEquals(
  "{foo: 'bar', baz: 'qux'}",
  JSONObject.fromObject("{foo: 'bar', baz: 'xyzzy'}")
);

Gibt:

junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>

Oder noch einfacher: JSONAssert.assertJsonEquals ("{foo: 'bar', baz: 'qux'}", {foo: 'bar', baz: 'xyzzy'} ")
Rob Juurlink

2
Während diese Lösung für die Reihenfolge der Datenelemente in JSON funktioniert, schlägt sie fehl, wenn die Reihenfolge der Elemente in Arrays nicht übereinstimmt. Wenn Ihr Code ein Set verwendet, das beispielsweise in JSON konvertiert wird. Der folgende JSON-Vergleich würde fehlschlagen: JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }"); Mit der Nachricht:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Dan Temple

Ja, dies ist eine Einschränkung von Json :(. Json.org zeigt, dass es kein ungeordnetes Sammlungstoken gibt. {} Kann nur Schlüssel-Wert-Paare umgeben. Dies ist sehr irritierend
Merk

15

Verwenden Sie diese Bibliothek: https://github.com/lukas-krecan/JsonUnit

Pom:

<dependency>
    <groupId>net.javacrumbs.json-unit</groupId>
    <artifactId>json-unit</artifactId>
    <version>1.5.0</version>
    <scope>test</scope>
</dependency>

IGNORING_ARRAY_ORDER - ignoriert die Reihenfolge in Arrays

assertJsonEquals("{\"test\":[1,2,3]}",
  "{\"test\":  [3,2,1]}",
  when(IGNORING_ARRAY_ORDER)
);

Kannst du weitere Kommentare hinzufügen, wie wir es verwenden können
Ran Adler

sichere Verwendung ist sehr einfach: Fügen Sie dies Ihrem Pom hinzu. <dependency> <groupId> net.javacrumbs.json-unit </ groupId> <artifactId> json-unit </ifactId> <version> 1.5.0 </ version> <scope> test </ scope> </ dependency>
Chethu

10x Ich habe mir die Anleitung unter dem Link angesehen und sie gefunden :)
Ran Adler

12

Wenn Sie JUnit bereits verwenden, wird in der neuesten Version jetzt Hamcrest verwendet. Es ist ein generisches Matching-Framework (besonders nützlich für Unit-Tests), das erweitert werden kann, um neue Matcher zu erstellen.

Es gibt eine kleine Open-Source-Bibliothek hamcrest-jsonmit JSON-fähigen Übereinstimmungen. Es ist gut dokumentiert, getestet und unterstützt. Unten finden Sie einige nützliche Links:

Beispielcode mit Objekten aus der JSON-Bibliothek org.json.simple:

Assert.assertThat(
    jsonObject1.toJSONString(),
    SameJSONAs.sameJSONAs(jsonObject2.toJSONString()));

Optional können Sie (1) Arrays beliebiger Reihenfolge zulassen und (2) zusätzliche Felder ignorieren.

Da es eine Vielzahl von JSON-Bibliotheken für Java gibt (Jackson , GSON, json-lib, etc.), ist es sinnvoll , dass hamcrest-jsonTräger JSON Text (wie java.lang.String) sowie native Objekte von Douglas Crockford JSON - Bibliothek unterstützt org.json.

Wenn Sie JUnit nicht verwenden, können Sie Hamcrest direkt für Zusicherungen verwenden. ( Ich habe hier darüber geschrieben. )


Was ist der Vorteil der Verwendung von Hamcrast-Matchern anstelle der direkten Verwendung von JSONAssert?
Johannes

2
@ Johannes: Nur Stil.
Kevinarpe

Die hamcrest-json-Quellen haben derzeit ein letztes Festschreibungsdatum von 2012. Es wird möglicherweise nicht mehr so ​​gut unterstützt.
Thorbjørn Ravn Andersen

11

Sie können JsonUnit ausprobieren . Es kann zwei JSON-Objekte vergleichen und Unterschiede melden. Es ist auf Jackson gebaut.

Beispielsweise

assertJsonEquals("{\"test\":1}", "{\n\"test\": 2\n}");

Ergebnisse in

java.lang.AssertionError: JSON documents are different:
Different value found in node "test". Expected 1, got 2.

6

Eine Sache, die ich getan habe und die Wunder wirkt, ist, beide Objekte in HashMap einzulesen und dann mit einem regulären assertEquals () zu vergleichen. Es wird die equals () -Methode der Hashmaps aufgerufen, die alle darin enthaltenen Objekte rekursiv vergleicht (es handelt sich entweder um andere Hashmaps oder um ein Einzelwertobjekt wie eine Zeichenfolge oder eine Ganzzahl). Dies wurde mit dem Jackson JSON-Parser von Codehaus durchgeführt.

assertEquals(mapper.readValue(expectedJson, new TypeReference<HashMap<String, Object>>(){}), mapper.readValue(actualJson, new TypeReference<HashMap<String, Object>>(){}));

Ein ähnlicher Ansatz kann verwendet werden, wenn das JSON-Objekt stattdessen ein Array ist.


6

Ich benutze dies und funktioniert gut für mich (mit org.json. *):

package com.project1.helpers;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class JSONUtils {

    public static boolean areEqual(Object ob1, Object ob2) throws JSONException {
        Object obj1Converted = convertJsonElement(ob1);
        Object obj2Converted = convertJsonElement(ob2);
        return obj1Converted.equals(obj2Converted);
    }

    private static Object convertJsonElement(Object elem) throws JSONException {
        if (elem instanceof JSONObject) {
            JSONObject obj = (JSONObject) elem;
            Iterator<String> keys = obj.keys();
            Map<String, Object> jsonMap = new HashMap<>();
            while (keys.hasNext()) {
                String key = keys.next();
                jsonMap.put(key, convertJsonElement(obj.get(key)));
            }
            return jsonMap;
        } else if (elem instanceof JSONArray) {
            JSONArray arr = (JSONArray) elem;
            Set<Object> jsonSet = new HashSet<>();
            for (int i = 0; i < arr.length(); i++) {
                jsonSet.add(convertJsonElement(arr.get(i)));
            }
            return jsonSet;
        } else {
            return elem;
        }
    }
}

4

Für org.json habe ich meine eigene Lösung eingeführt, eine Methode, die mit JSONObject-Instanzen verglichen wird. Ich habe in diesem Projekt nicht mit komplexen JSON-Objekten gearbeitet, daher weiß ich nicht, ob dies in allen Szenarien funktioniert. Da ich dies in Unit-Tests verwende, habe ich mich auch nicht um Optimierungen bemüht. Hier ist es:

public static boolean jsonObjsAreEqual (JSONObject js1, JSONObject js2) throws JSONException {
    if (js1 == null || js2 == null) {
        return (js1 == js2);
    }

    List<String> l1 =  Arrays.asList(JSONObject.getNames(js1));
    Collections.sort(l1);
    List<String> l2 =  Arrays.asList(JSONObject.getNames(js2));
    Collections.sort(l2);
    if (!l1.equals(l2)) {
        return false;
    }
    for (String key : l1) {
        Object val1 = js1.get(key);
        Object val2 = js2.get(key);
        if (val1 instanceof JSONObject) {
            if (!(val2 instanceof JSONObject)) {
                return false;
            }
            if (!jsonObjsAreEqual((JSONObject)val1, (JSONObject)val2)) {
                return false;
            }
        }

        if (val1 == null) {
            if (val2 != null) {
                return false;
            }
        }  else if (!val1.equals(val2)) {
            return false;
        }
    }
    return true;
}

1
Da Sie Optimierungen erwähnt haben :), wenn val1null ist, erhalten Sie eine NullPointerException von diesem Codeif (!val1.equals(val2)) {
JohnDoDo

Es passiert auch den Besten von uns :). +1 für die Korrektur in Ihrer Antwort.
JohnDoDo

Punkt genommen :) Hoffe, dass es nicht zu viele Stimmen bekommt, sonst wird es viel Unterstützung geben.
Victor Ionescu

1
Sie haben nicht überlegt, ob es js2ist nulloder nicht, wann js1nichtnull
Xiao

Dieser Code funktioniert nicht für verschachtelte Objekte / Sequenzen.
FabienB

3

Sie können die zjsonpatch- Bibliothek verwenden, die die Diff-Informationen gemäß RFC 6902 (JSON-Patch) darstellt. Es ist sehr einfach zu bedienen. Bitte besuchen Sie die Beschreibungsseite für die Verwendung


2

Ich würde die Bibliothek unter http://json.org/java/ nehmen und die equalsMethode von JSONObject und JSONArray ändern, um einen tiefen Gleichheitstest durchzuführen. Um sicherzustellen, dass es unabhängig von der Reihenfolge der Kinder funktioniert, müssen Sie lediglich die innere Karte durch eine ersetzen TreeMapoder etwas Ähnliches verwenden Collections.sort().


4
es ist nicht so toll - es hätte wirklich mit Code kommen sollen, um einen json-Vergleich durchzuführen.
Chii

Aber stellen Sie sich vor, Sie schreiben diesen Code, in dem JSON alles in jeder Struktur sein kann ... schreiben Sie den Vergleich dazu! Es ist so, als würde man einen Vergleich für alle Arten von HTML-Seiten schreiben.
JPM

2

Versuche dies:

public static boolean jsonsEqual(Object obj1, Object obj2) throws JSONException

    {
        if (!obj1.getClass().equals(obj2.getClass()))
        {
            return false;
        }

        if (obj1 instanceof JSONObject)
        {
            JSONObject jsonObj1 = (JSONObject) obj1;

            JSONObject jsonObj2 = (JSONObject) obj2;

            String[] names = JSONObject.getNames(jsonObj1);
            String[] names2 = JSONObject.getNames(jsonObj1);
            if (names.length != names2.length)
            {
                return false;
            }

            for (String fieldName:names)
            {
                Object obj1FieldValue = jsonObj1.get(fieldName);

                Object obj2FieldValue = jsonObj2.get(fieldName);

                if (!jsonsEqual(obj1FieldValue, obj2FieldValue))
                {
                    return false;
                }
            }
        }
        else if (obj1 instanceof JSONArray)
        {
            JSONArray obj1Array = (JSONArray) obj1;
            JSONArray obj2Array = (JSONArray) obj2;

            if (obj1Array.length() != obj2Array.length())
            {
                return false;
            }

            for (int i = 0; i < obj1Array.length(); i++)
            {
                boolean matchFound = false;

                for (int j = 0; j < obj2Array.length(); j++)
                {
                    if (jsonsEqual(obj1Array.get(i), obj2Array.get(j)))
                    {
                        matchFound = true;
                        break;
                    }
                }

                if (!matchFound)
                {
                    return false;
                }
            }
        }
        else
        {
            if (!obj1.equals(obj2))
            {
                return false;
            }
        }

        return true;
    }

Innerhalb von jsonArrays gibt dies true zurück, wenn einige der Elemente übereinstimmen, im Gegensatz zu allen Elementen.
Matiasg

@matiasg - stellt das if (obj1Array.length() != obj2Array.length())nicht sicher, dass alle Elemente übereinstimmen?
Kwah

3
@ Kwah: Nein. Betrachten Sie dieses Beispiel: obj1Array = [1,1,1], obj2Array = [1,2,3]. Dies würde wahr zurückgeben. Auch wenn Elemente zusammenfallen, sollten sie in derselben Reihenfolge sein. Dies würde auch für [1,2,3] und [2,3,1] zutreffen, was falsch ist
Matiasg


2

Karate ist genau das, wonach Sie suchen. Hier ist ein Beispiel:

* def myJson = { foo: 'world', hey: 'ho', zee: [5], cat: { name: 'Billie' } }
* match myJson = { cat: { name: 'Billie' }, hey: 'ho', foo: 'world', zee: [5] }

(Haftungsausschluss: dev hier)


2

Zum Vergleichen von jsons empfehle ich die Verwendung von JSONCompare: https://github.com/fslev/json-compare

// Compare by regex
String expected = "{\"a\":\".*me.*\"}";
String actual = "{\"a\":\"some text\"}";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no extra elements
String expected = "[1,\"test\",4,\"!.*\"]";
String actual = "[4,1,\"test\"]";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[\"text\",\"test\"]";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[2018]";
JSONCompare.assertNotEquals(expected, actual);  // True

0

Für diejenigen wie mich, die dies mit Jackson machen wollen, können Sie json-unit verwenden .

JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);

Die Fehler geben nützliche Rückmeldungen zur Art der Nichtübereinstimmung:

java.lang.AssertionError: JSON documents have different values:
Different value found in node "heading.content[0].tag[0]". Expected 10209, got 10206.

0

Nichts anderes schien ganz richtig zu funktionieren, also schrieb ich Folgendes:

private boolean jsonEquals(JsonNode actualJson, JsonNode expectJson) {
    if(actualJson.getNodeType() != expectJson.getNodeType()) return false;

    switch(expectJson.getNodeType()) {
    case NUMBER:
        return actualJson.asDouble() == expectJson.asDouble();
    case STRING:
    case BOOLEAN:
        return actualJson.asText().equals(expectJson.asText());
    case OBJECT:
        if(actualJson.size() != expectJson.size()) return false;

        Iterator<String> fieldIterator = actualJson.fieldNames();
        while(fieldIterator.hasNext()) {
            String fieldName = fieldIterator.next();
            if(!jsonEquals(actualJson.get(fieldName), expectJson.get(fieldName))) {
                return false;
            }
        }
        break;
    case ARRAY:
        if(actualJson.size() != expectJson.size()) return false;
        List<JsonNode> remaining = new ArrayList<>();
        expectJson.forEach(remaining::add);
        // O(N^2)   
        for(int i=0; i < actualJson.size(); ++i) {
            boolean oneEquals = false;
            for(int j=0; j < remaining.size(); ++j) {
                if(jsonEquals(actualJson.get(i), remaining.get(j))) {
                    oneEquals = true;
                    remaining.remove(j);
                    break;
                }
            }
            if(!oneEquals) return false;
        }
        break;
    default:
        throw new IllegalStateException();
    }
    return true;
}

0

Der folgende Code ist hilfreicher, um zwei JsonObject, JsonArray, JsonPrimitive und JasonElements zu vergleichen.

private boolean compareJson(JsonElement json1, JsonElement json2) {
        boolean isEqual = true;
        // Check whether both jsonElement are not null
        if (json1 != null && json2 != null) {

            // Check whether both jsonElement are objects
            if (json1.isJsonObject() && json2.isJsonObject()) {
                Set<Entry<String, JsonElement>> ens1 = ((JsonObject) json1).entrySet();
                Set<Entry<String, JsonElement>> ens2 = ((JsonObject) json2).entrySet();
                JsonObject json2obj = (JsonObject) json2;
                if (ens1 != null && ens2 != null) {
                    // (ens2.size() == ens1.size())
                    // Iterate JSON Elements with Key values
                    for (Entry<String, JsonElement> en : ens1) {
                        isEqual = isEqual && compareJson(en.getValue(), json2obj.get(en.getKey()));
                    }
                } else {
                    return false;
                }
            }

            // Check whether both jsonElement are arrays
            else if (json1.isJsonArray() && json2.isJsonArray()) {
                JsonArray jarr1 = json1.getAsJsonArray();
                JsonArray jarr2 = json2.getAsJsonArray();
                if (jarr1.size() != jarr2.size()) {
                    return false;
                } else {
                    int i = 0;
                    // Iterate JSON Array to JSON Elements
                    for (JsonElement je : jarr1) {
                        isEqual = isEqual && compareJson(je, jarr2.get(i));
                        i++;
                    }
                }
            }

            // Check whether both jsonElement are null
            else if (json1.isJsonNull() && json2.isJsonNull()) {
                return true;
            }

            // Check whether both jsonElement are primitives
            else if (json1.isJsonPrimitive() && json2.isJsonPrimitive()) {
                if (json1.equals(json2)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else if (json1 == null && json2 == null) {
            return true;
        } else {
            return false;
        }
        return isEqual;
    }


0

Als ich mir die Antworten ansah, versuchte ich es mit JSONAssert, aber es schlug fehl. Also habe ich Jackson mit zjsonpatch benutzt. Ich habe Details in der SO-Antwort hier gepostet .


-5

Diese Lösung ist für mich sehr gut:

try {           
                // Getting The Array "Courses" from json1 & json2   
                Courses1 =json1.getJSONArray(TAG_COURSES1);
                Courses2 = json2.getJSONArray(TAG_COURSES);

                //LOOP FOR JSON1
                for(int i = 0; i < Courses1.length(); i++){
                    //LOOP FOR JSON2
                    for(int ii = 0; ii < Courses2.length(); ii++){
                        JSONObject courses1 = Courses1.getJSONObject(i);
                        JSONObject courses2 = Courses2.getJSONObject(ii);

                        // Storing each json1 item in variable
                        int courseID1 = courses1.getInt(TAG_COURSEID1);
                        Log.e("COURSEID2:", Integer.toString(courseID1));
                        String Rating1 = courses1.getString(TAG_RATING1);
                        int Status1 = courses1.getInt(TAG_STATUS1);
                        Log.e("Status1:", Integer.toString(Status1));      //Put the actual value for Status1 in log.             

                        // Storing each json2 item in variable
                        int courseID2 = courses2.getInt(TAG_COURSEID);
                        Log.e("COURSEID2:", Integer.toString(courseID));   //Put the actual value for CourseID in log
                        String Title2 = courses2.getString(TAG_TITLE);                      
                        String instructor2 = courses2.getString(TAG_INSTRUCTOR);
                        String length2 = courses2.getString(TAG_LENGTH);
                        String rating2 = courses2.getString(TAG_RATING);
                        String subject2 = courses2.getString(TAG_SUBJECT);
                        String description2 = courses2.getString(TAG_DESCRIPTION);

                        //Status1 = 5 from json1; Incomplete, Status1 =-1 Complete 
                        if(Status1 == 5 && courseID2 == courseID1){                                  

                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();         
                        //Storing the elements if condition is true.
                        map.put(TAG_COURSEID, Integer.toString(courseID2)); //pend for compare
                        map.put(TAG_TITLE, Title2);
                        map.put(TAG_INSTRUCTOR, instructor2);
                        map.put(TAG_LENGTH, length2);
                        map.put(TAG_RATING, rating2);
                        map.put(TAG_SUBJECT, subject2); //show it
                        map.put(TAG_DESCRIPTION, description2);

                        //adding HashList to ArrayList
                        contactList.add(map);
                        }//if
                    }//for2 (json2)
                } //for1 (json1)                
            }//Try

Hoffe das hilft anderen.


Natürlich, geben Sie in diesem Fall einfach Ihre Werte und Bedingungen sowie die Art der Sichtweise an. Hashmap über eine Listenansicht.
JLouis

1
Dies ist ein schönes Beispiel dafür, wie man es nicht macht :)
Petr Újezdský
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.