Testowanie dwóch obiektów JSON pod kątem równości, ignorując kolejność dzieci w Javie

233

Szukam biblioteki analizującej JSON, która obsługuje porównywanie dwóch obiektów JSON ignorujących kolejność elementów podrzędnych, szczególnie do testowania jednostkowego JSON powracającego z usługi WWW.

Czy którakolwiek z głównych bibliotek JSON obsługuje to? Biblioteka org.json po prostu porównuje odniesienia.

Jeff
źródło
1
Nie można serializować obu obiektów do reprezentacji ciągów i porównywać? Chyba wszystkie biblioteki obsługują toString()konwersję obiektu na JSONciąg.
Teja Kantamneni,
47
Zakłada to, że kolejność serializacji do i z ciągów znaków jest zawsze taka sama. Nie czuję się dobrze, przyjmując takie założenie.
Jeff
Masz rację Jeff, to wcale nie jest bezpieczne. Ten test pokazuje scenariusz, w którym odwzorowania są takie same, ale toString () nie zwraca tego samego wyniku: gist.github.com/anonymous/5974797 . Wynika to z faktu, że podstawowa HashMap może się powiększać, a jeśli usuniesz klucze, wewnętrzna tablica HashMap się nie kurczy.
Guillaume Perrot

Odpowiedzi:

84

Jako ogólny punkt architektoniczny zwykle odradzam uwalnianie zależności od określonego formatu serializacji poza warstwę pamięci / sieci; dlatego najpierw zaleciłbym rozważenie przetestowania równości między własnymi obiektami aplikacji, a nie ich manifestacjami JSON.

Powiedziawszy to, jestem obecnie wielkim fanem Jacksona, który mój szybki odczyt ich implementacji ObjectNode.equals () sugeruje, czy zestaw porównawczy członkostwa, który chcesz:

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;
}
Jolly Roger
źródło
Ta metoda nie jest symetryczna, ponieważ testuje jedynie relacje „podzbioru” dzieci, a nie równość. „inny” obiekt może mieć więcej dzieci niż u dzieci, a ta metoda nadal zwróciłaby wartość true.
Yoni
23
@Yoni: Nieprawda, ponieważ istnieje porównanie rozmiarów. Muszą mieć dokładnie taką samą liczbę dzieci, jak i te same dzieci. @Jolly Roger: W tym przypadku nie serializuję obiektu z JSON z powrotem do POJO, ale wysyłając JSON system, który to robi, nie mogę polegać na tym, że odsyła go w dokładnie takim samym formacie, w jakim wysłałem to.
Jeff
1
@Jeff Czy to działało dla Ciebie? W junit assertEquals kończy się niepowodzeniem. Projekt używa starej wersji (1.5), fyi.
ronnyfm,
1
Myślę, że brakuje ci testów wysokiego poziomu, jeśli nie zapewniasz JSON. Możesz mieć cienki test, który wysyła żądanie HTTP i odpowiada oczekiwanym JSON - jest to główne zachowanie funkcjonalne usługi internetowej.
mogronalol
Tylko niewielka uwaga dotycząca wydajności: kod, który porównuje „wartość” z „otherValue”, można uprościć, jeśli (wartość.equals (other.get (klucz)) zwróci wartość false; jako że „wartość” z pewnością nie jest równa zeru i Metoda equals () JsonNode'a powinna zaakceptować argument zerowy
Tillmann
154

Wypróbuj JSONAssert w Skyscreamer .

Jego zakaz ścisłe tryb ma dwie główne zalety, które czynią go mniej kruche:

  • Rozszerzalność obiektu (np. Przy oczekiwanej wartości {id: 1} , to i tak dałoby wynik: {id: 1, moredata: 'x'} .)
  • Luźna kolejność tablic (np. [„Pies”, „kot”] == [„kot”, „pies”])

W trybie ścisłym zachowuje się bardziej jak klasa testowa json-lib.

Test wygląda mniej więcej tak:

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

Parametry w wywołaniu JSONAssert.assertEquals () są oczekiwane : JSONString , actualDataString i isStrict .

Komunikaty wyników są dość wyraźne, co jest ważne przy porównywaniu naprawdę dużych obiektów JSON.

Strona Carter
źródło
18
Korzystałem z tego rozwiązania, ale właśnie odkryłem, że możesz również podać wybrany przez Ciebie JSONCompareMode. Jednym z nich jest NON_EXTENSIBLE. Więc masz coś takiego: JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);Tryb NON_EXTENSIBLE oznacza, że ​​wszelkie nowe lub brakujące pola powodują awarie, ale kolejność nie. Użycie false spowoduje uruchomienie trybu łagodnego, który nie zgłosi żadnych dodatkowych lub brakujących elementów potomnych.
Dan Temple,
1
Tryb porównania NON_EXTENSIBLE jest dokładnie tym , czego szukałem. Dzięki za to, Dan.
ThoughtCrhyme,
Zanim się podekscytuję: czy ta obsługa zagnieżdża również obiekty JSON i tablice? :)
Christian
2
Ludzie mogą chcieć wziąć pod uwagę ten problem JSONassert przed użyciem biblioteki: oznacza to, że istnieją obecnie potencjalne problemy z licencjonowaniem w zależności od biblioteki.
Chriki,
3
Naprawiono błąd JSONAssert nr 44, zastępując bibliotekę clean-room w PR 67, wydany dzisiaj jako JSONAssert 1.4.0.
Carter Page
49

Korzystanie z 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);

Edycja: Od wersji GSON v2.8.6 metoda instancji JsonParser.parsejest przestarzała. Musisz użyć metody statycznej JsonParser.parseString:

JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);
axelhzf
źródło
Działa dla mnie w GSON 2.8.2.
Tom Saleeba
1
nie działa, jeśli elementy jsonArray nie są w porządku. wersja 2.8.2
Naveen Kumar RB
1
Nie działa dla mnie, jeśli kolejność obiektu / elementu jest inna
Jknair
Działa to dla mnie, ponieważ chciałem go tylko do testu jednostkowego, w którym właściwości dwóch jsonów miały tę samą kolejność
GabrielBB
@GabrielBB Powinieneś edytować pytanie i wskazać, w jakiej wersji API jest przestarzałe, iw jakiej wersji zaczyna działać nowy styl kodu.
jasne
30

Zrobiłbym następujące,

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);
josh
źródło
Jeśli używasz już Jacksona, to najlepsza odpowiedź IMHO.
Christoph Dietze
18
ale myślę, że jest to ścisłe porównanie. Zwróci wartość false dla dwóch równych jsonów o różnej kolejności elementów.
Deadpool
@deadpool zasada jest zdrowa, wystarczy zmienić porównanie, aby być bardziej zaangażowanym (na przykład sprawdzanie kluczowych pól, a nie zwykłych drzewek).
jwenting
To najlepsza odpowiedź na świecie. Nie tylko odpowiada teraz na moje pytanie, ale także odpowiada na prawie każde porównanie obiektów, które musimy wykonać. dzięki, joshu.
Luiz Feijão Veronesi
2
@deadpool, być może było to ścisłe porównanie, ale teraz nie jest ścisłe.
Andrei Damian-Fekete
18

Możesz spróbować użyć klasy JSONAssert json-lib :

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

Daje:

junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>
hertzsprung
źródło
Lub nawet prościej: JSONAssert.assertJsonEquals („{foo: 'bar', baz: 'qux'} ', {foo:' bar ', baz:' xyzzy '}”);
Rob Juurlink
2
Chociaż to rozwiązanie działa w przypadku kolejności elementów danych w JSON, zakończy się niepowodzeniem, jeśli kolejność elementów w tablicach nie będzie zgodna. Jeśli kod używa zestawu, który jest na przykład konwertowany na JSON. Następujące porównanie JSON nie powiedzie się: JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }"); Komunikat:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Dan Temple
Tak, jest to ograniczenie Json :(. Json.org pokazuje, że nie ma nieuporządkowanego tokenu kolekcji. {} Może otaczać tylko pary klucz-wartość. Jest to bardzo irytujące
Merk
15

Użyj tej biblioteki: 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 - ignoruje kolejność w tablicach

assertJsonEquals("{\"test\":[1,2,3]}",
  "{\"test\":  [3,2,1]}",
  when(IGNORING_ARRAY_ORDER)
);
chethu
źródło
czy możesz dodać więcej komentarzy na temat tego, jak możemy go używać? Dodaję go do mojej pom, ale potrzebujemy doc, aby zrozumieć, jak go używać
Ran Adler,
pewna obsługa jest bardzo prosta: dodaj to do pom. <dependency> <groupId> net.javacrumbs.json-unit </groupId> <artifactId> json-unit </artifactId> <version> 1.5.0 </version> <scope> test </scope> </dependency>
chethu
10x spojrzałem na instrukcję pod linkiem i znalazłem ją :)
Ran Adler
12

Jeśli już używasz JUnit, najnowsza wersja zawiera teraz Hamcrest. Jest to ogólna struktura dopasowywania (szczególnie przydatna do testowania jednostkowego), którą można rozszerzyć w celu zbudowania nowych dopasowań.

Istnieje mała biblioteka open source o nazwie hamcrest-jsonz dopasowaniami JSON. Jest dobrze udokumentowany, przetestowany i obsługiwany. Poniżej znajdują się przydatne linki:

Przykładowy kod wykorzystujący obiekty z biblioteki JSON org.json.simple:

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

Opcjonalnie możesz (1) zezwolić na tablice „dowolnego rzędu” i (2) zignorować dodatkowe pola.

Ponieważ istnieje wiele bibliotek JSON for Java ( Jackson, GSON, json-lib, itd), jest przydatna, że hamcrest-jsontekst podpory JSON (jak java.lang.String), a także obiekty wspierające natywnie z JSON biblioteki Douglasa Crockforda użytkownika org.json.

Wreszcie, jeśli nie używasz JUnit, możesz użyć Hamcrest bezpośrednio do asercji. ( Pisałem o tym tutaj. )

kevinarpe
źródło
Jaka jest zaleta używania dopasowywania hamcrast zamiast bezpośredniego używania JSONAssert?
Johannes,
2
@Johannes: Tylko styl.
kevinarpe
Źródła hamcrest-json mają obecnie datę ostatniego zatwierdzenia w 2012 r. Może nie być już tak dobrze wspierane.
Thorbjørn Ravn Andersen
11

Możesz wypróbować JsonUnit . Może porównywać dwa obiekty JSON i zgłaszać różnice. Jest zbudowany na Jacksonie.

Na przykład

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

Prowadzi do

java.lang.AssertionError: JSON documents are different:
Different value found in node "test". Expected 1, got 2.
Lukas
źródło
6

Jedną rzeczą, którą zrobiłem i działa cuda, jest odczytanie obu obiektów do HashMap, a następnie porównanie ze zwykłą funkcją assertEquals (). Wywoła metodę haszaps równą (), która rekurencyjnie porównuje wszystkie obiekty w środku (będą to albo inne haszapy, albo jakiś obiekt o pojedynczej wartości, taki jak łańcuch lub liczba całkowita). Dokonano tego przy użyciu analizatora składni JSON firmy Codehaus.

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

Podobne podejście można zastosować, jeśli obiekt JSON jest tablicą.

Claudio Aguiar
źródło
6

Używam tego i działa dobrze dla mnie (z 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;
        }
    }
}
łapacz
źródło
4

W przypadku org.json wdrożyłem własne rozwiązanie, metodę porównywalną z instancjami JSONObject. W tym projekcie nie pracowałem ze złożonymi obiektami JSON, więc nie wiem, czy to działa we wszystkich scenariuszach. Biorąc pod uwagę, że używam tego w testach jednostkowych, nie wkładałem wysiłku w optymalizacje. Oto on:

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;
}
Victor Ionescu
źródło
1
Ponieważ wspomniałeś o optymalizacji :), jeśli val1jest null, otrzymasz wyjątek NullPointerException z tego koduif (!val1.equals(val2)) {
JohnDoDo
Zdarza się także najlepszemu z nas :). +1 za naprawienie go w swojej odpowiedzi.
JohnDoDo
punkt wzięty :) Mam nadzieję, że nie zdobędzie on jednak zbyt wielu głosów, w przeciwnym razie będzie dużo wsparcia.
Victor Ionescu
1
Nie zastanawiałeś się, czy js2jest, nullczy nie, kiedy js1nie manull
Xiao
Ten kod nie działa dla zagnieżdżonych obiektów / sekwencji.
FabienB
3

Możesz użyć biblioteki zjsonpatch , która przedstawia informacje o różnicach zgodnie z RFC 6902 (łatka JSON). Jest bardzo łatwy w użyciu. Proszę odwiedzić jego stronę z opisem użycia

Gopi Vishwakarma
źródło
2

Wziąłbym bibliotekę pod adresem http://json.org/java/ i zmodyfikowałem equalsmetodę JSONObject i JSONArray, aby przeprowadzić głęboki test równości. Aby upewnić się, że działa bez względu na kolejność dzieci, wystarczy wymienić wewnętrzną mapę na TreeMaplub użyć czegoś podobnego Collections.sort().

Yoni
źródło
4
nie jest tak świetny - naprawdę powinien był mieć kod do porównania JSON.
Chii
Ale wyobraź sobie pisanie tego kodu, w którym JSON może być dowolnym elementem w dowolnej strukturze ... napisz porównanie! To jak pisanie porównania dla wszystkich typów stron HTML.
JPM,
2

Spróbuj tego:

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;
    }
Misza
źródło
w jsonArrays zwraca wartość true, jeśli niektóre elementy się pokrywają, w przeciwieństwie do wszystkich elementów.
matiasg
@matiasg - czy if (obj1Array.length() != obj2Array.length())nie gwarantuje, że wszystkie elementy się pokrywają?
kwah
3
@kwah: nope. Rozważ ten przykład: obj1Array = [1,1,1], obj2Array = [1,2,3]. To zwróci prawdę. Ponadto, nawet jeśli elementy się pokrywają, powinny być w tej samej kolejności. Zwróciłoby to również prawdę dla [1,2,3] i [2,3,1], co jest błędne
matiasg
2

Wiem, że to jest zwykle uważane tylko do testów, ale można użyć Hamcrest JSON comparitorSameJSONAs w Hamcrest JSON.

Hamcrest JSON SameJSONAs

Justin Ohms
źródło
2

Karate jest dokładnie tym, czego szukasz. Oto przykład:

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

(wyłączenie odpowiedzialności: tutaj programista)

Peter Thomas
źródło
2

Do porównania jsonów polecam użycie 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
Slev Florin
źródło
0

Dla takich jak ja, którzy chcą to zrobić z Jacksonem, możesz użyć json-unit .

JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);

Błędy dają użyteczne informacje zwrotne na temat rodzaju niedopasowania:

java.lang.AssertionError: JSON documents have different values:
Different value found in node "heading.content[0].tag[0]". Expected 10209, got 10206.
Krookedking
źródło
0

Nic innego nie działało całkiem dobrze, więc napisałem to:

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;
}
Alex R.
źródło
0

Poniższy kod będzie bardziej pomocny w porównaniu dwóch JsonObject, JsonArray, JsonPrimitive i JasonElements.

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;
    }
Radadiya Nikunj
źródło
0

Patrząc na odpowiedzi, spróbowałem JSONAssert, ale nie udało się. Więc użyłem Jacksona z zjsonpatch. Podałem szczegóły w odpowiedzi SO tutaj .

likejudo
źródło
-5

To rozwiązanie jest dla mnie bardzo dobre:

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

Mam nadzieję, że pomoże to innym.

JLouis
źródło
oczywiście, po prostu podaj swoje wartości i warunki oraz rodzaj widoku, w tym przypadku; Hashmapa nad widokiem listy.
JLouis,
1
To
dobry