Menguji dua objek JSON untuk kesetaraan mengabaikan pesanan anak di Jawa

233

Saya mencari perpustakaan parsing JSON yang mendukung membandingkan dua objek JSON mengabaikan pesanan anak, khusus untuk pengujian unit JSON kembali dari layanan web.

Apakah ada perpustakaan JSON utama yang mendukung ini? Pustaka org.json hanya melakukan perbandingan referensi.

Jeff
sumber
1
Tidak dapat membuat serialisasi kedua objek ke representasi string dan membandingkan? Saya kira semua dukungan perpustakaan toString()untuk mengubah objek menjadi JSONstring.
Teja Kantamneni
47
Itu mengasumsikan bahwa urutan serialisasi ke dan dari string selalu sama. Saya tidak nyaman membuat asumsi itu.
Jeff
Kamu benar Jeff, tidak aman sama sekali. Tes ini menunjukkan skenario di mana pemetaan adalah sama tetapi toString () tidak mengembalikan output yang sama: gist.github.com/anonymous/5974797 . Ini karena HashMap yang mendasarinya dapat tumbuh, dan jika Anda menghapus kunci, array internal HashMap tidak menyusut.
Guillaume Perrot

Jawaban:

84

Sebagai titik arsitektur umum, saya biasanya menyarankan agar tidak membiarkan dependensi pada format serialisasi tertentu keluar dari lapisan penyimpanan / jaringan Anda; jadi, saya pertama-tama menyarankan Anda mempertimbangkan pengujian kesetaraan antara objek aplikasi Anda sendiri daripada manifestasi JSON mereka.

Karena itu, saya saat ini penggemar berat Jackson yang saya baca cepat dari ObjectNode.equals () implementasi mereka menunjukkan apakah perbandingan keanggotaan set yang Anda inginkan:

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
sumber
Metode ini tidak simetris, karena hanya menguji hubungan 'subset' anak-anak, bukan kesetaraan. objek 'lain' mungkin memiliki lebih banyak anak di _children, dan metode ini masih akan kembali benar.
Yoni
23
@ Yoni: Tidak benar, karena ada perbandingan ukuran. Mereka harus memiliki jumlah anak yang sama persis seperti halnya anak yang sama. @Jolly Roger: Dalam hal ini, saya tidak membuat serialisasi objek dari JSON kembali ke POJO, tetapi ketika mengirim JSON sistem yang berfungsi, saya tidak bisa mengandalkannya mengirimnya kembali dalam format yang sama persis dengan yang saya kirim Itu.
Jeff
1
@ Jeff Apakah ini berhasil untuk Anda? Di junit, assertEquals gagal untuk saya. Proyek ini menggunakan versi lama (1.5), fyi.
ronnyfm
1
Saya pikir Anda melewatkan beberapa pengujian tingkat tinggi jika Anda tidak menyatakan JSON. Anda dapat melakukan tes tipis yang membuat permintaan http dan merespons dengan beberapa JSON yang diharapkan - ini adalah perilaku fungsional utama dari layanan web.
mogronalol
Hanya catatan kecil mengenai kinerja: kode yang membandingkan 'nilai' dengan 'Nilai lain' dapat disederhanakan menjadi jika (value.equals (other.get (key)) mengembalikan false, karena 'nilai' dijamin tidak-nol dan Metode equals () JsonNode harus menerima argumen nol
Tillmann
154

Coba Skyscreamer ini JSONAssert .

Its non-ketat mode memiliki dua keunggulan utama yang membuatnya kurang rapuh:

  • Ekstensibilitas objek (mis. Dengan nilai yang diharapkan dari {id: 1} , ini masih akan berlalu: {id: 1, moredata: 'x'} .)
  • Pemesanan array yang longgar (mis. ['Anjing', 'kucing'] == ['kucing', 'anjing'])

Dalam mode ketat itu berperilaku lebih seperti kelas uji json-lib.

Tes terlihat seperti ini:

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

Parameter dalam panggilan JSONAssert.assertEquals () diharapkanJSONString , actualDataString , dan isStrict .

Pesan hasil cukup jelas, yang penting ketika membandingkan objek JSON yang sangat besar.

Halaman Carter
sumber
18
Saya telah menggunakan solusi ini, tetapi saya baru saja menemukan bahwa Anda juga bisa memberikan JSONCompareMode yang Anda pilih. Salah satunya adalah NON_EXTENSIBLE. Jadi Anda akan memiliki sesuatu seperti ini: JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);Mode NON_EXTENSIBLE berarti bahwa setiap bidang baru atau yang hilang menyebabkan kegagalan, tetapi urutannya tidak. Menggunakan false akan memicu mode lunak yang tidak akan melaporkan elemen anak tambahan atau hilang.
Dan Temple
1
Mode perbandingan NON_EXTENSIBLE persis seperti yang saya cari. Terima kasih untuk ini, Dan.
ThoughtCrhyme
Sebelum saya menjadi bersemangat: apakah ini mendukung objek dan array JSON yang bersarang? :)
Christian
2
Orang-orang mungkin ingin mempertimbangkan masalah JSONassert ini sebelum menggunakan perpustakaan: ini menunjukkan bahwa saat ini ada masalah lisensi potensial dengan ketergantungan perpustakaan.
Chriki
3
Masalah JSONAssert # 44 diperbaiki dengan penggantian perpustakaan kamar-bersih di PR 67, dirilis hari ini sebagai JSONAssert 1.4.0.
Halaman Carter
49

Menggunakan 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);

Sunting: Sejak GSON v2.8.6 metode instance JsonParser.parsetidak digunakan lagi. Anda harus menggunakan metode statis JsonParser.parseString:

JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);
axelhzf
sumber
Bekerja di GSON 2.8.2 untuk saya.
Tom Saleeba
1
itu tidak berfungsi jika elemen jsonArray tidak berurutan. versi 2.8.2
Naveen Kumar RB
1
Tidak Bekerja untuk saya jika urutan objek / elemen berbeda
Jknair
Itu bekerja untuk saya karena saya hanya menginginkannya untuk unit test di mana dua properti jsons memiliki urutan yang sama
GabrielBB
@GabrielBB Anda harus mengedit pertanyaan dan menunjukkan versi apa API tidak digunakan lagi, dan dalam versi apa gaya kode yang baru mulai bekerja.
clearlight
30

Saya akan melakukan yang berikut,

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);
Astaga
sumber
Jika Anda sudah menggunakan Jackson, inilah jawaban IMHO terbaik.
Christoph Dietze
18
tapi saya pikir ini perbandingan yang ketat. Ini akan mengembalikan false untuk dua json yang sama memiliki urutan elemen yang berbeda.
deadpool
@deadpool, prinsipnya adalah suara, Anda hanya perlu mengubah perbandingan agar lebih terlibat (memeriksa bidang-bidang utama misalnya, bukan sama dengan pohon yang sama).
jwenting
Ini jawaban terbaik yang pernah ada. Tidak hanya menjawab pertanyaan saya sekarang, karena juga menjawab hampir setiap perbandingan objek yang perlu kita lakukan. terima kasih, joshu.
Luiz Feijão Veronesi
2
@deadpool, ini mungkin perbandingan yang ketat, tetapi tidak ketat sekarang.
Andrei Damian-Fekete
18

Anda bisa mencoba menggunakan kelas JSONAssert json-lib :

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

Memberi:

junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>
hertzsprung
sumber
Atau bahkan lebih sederhana: JSONAssert.assertJsonEquals ("{foo: 'bar', baz: 'qux'}", {foo: 'bar', baz: 'xyzzy'} ");
Rob Juurlink
2
Sementara solusi ini berfungsi untuk urutan item data dalam JSON, akan gagal jika urutan elemen dalam array tidak cocok. Jika kode Anda menggunakan Set yang dikonversi ke JSON misalnya. Perbandingan JSON berikut ini akan gagal: JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }"); Dengan pesan:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Dan Temple
Ya, ini adalah batasan dari Json :(. Json.org menunjukkan bahwa tidak ada token pengumpulan yang tidak diurutkan. {} Hanya dapat mengelilingi pasangan nilai kunci. Ini sangat menjengkelkan
Merk
15

Gunakan perpustakaan ini: 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 - mengabaikan urutan dalam array

assertJsonEquals("{\"test\":[1,2,3]}",
  "{\"test\":  [3,2,1]}",
  when(IGNORING_ARRAY_ORDER)
);
chethu
sumber
dapatkah Anda menambahkan lebih banyak komentar bagaimana kami dapat menggunakannya, saya menambahkannya ke pom saya, tetapi kami membutuhkan dokumen untuk memahami bagaimana menggunakannya
Ran Adler
yakin penggunaannya sangat sederhana: Tambahkan ini ke pom Anda. <dependency> <groupId> net.javacrumbs.json-unit </groupId> <artifactId> unit json </artifactId> <version> 1.5.0 </version> <scope> test </scope> </dependency>
chethu
10x saya telah melihat instruksi pada tautan dan saya menemukannya :)
Ran Adler
12

Jika Anda sudah menggunakan JUnit, versi terbaru sekarang menggunakan Hamcrest. Ini adalah kerangka kerja pencocokan umum (terutama berguna untuk pengujian unit) yang dapat diperluas untuk membangun pencocokan baru.

Ada perpustakaan open source kecil yang disebut hamcrest-jsondengan pencocokan yang menyadari JSON. Itu didokumentasikan dengan baik, diuji, dan didukung. Berikut ini beberapa tautan bermanfaat:

Kode contoh menggunakan objek dari perpustakaan JSON org.json.simple:

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

Secara opsional, Anda dapat (1) mengizinkan array "pesanan apa pun" dan (2) mengabaikan bidang tambahan.

Karena ada berbagai perpustakaan JSON untuk Java ( Jackson, GSON, json-lib, dll), hal ini berguna bahwa hamcrest-jsondukungan JSON teks (sebagai java.lang.String), benda-benda serta native mendukung dari perpustakaan JSON Douglas Crockford org.json.

Akhirnya, jika Anda tidak menggunakan JUnit, Anda dapat menggunakan Hamcrest secara langsung untuk pernyataan. ( Saya menulis tentang itu di sini. )

kevinarpe
sumber
Apa keuntungan menggunakan pencocokan hamcrast daripada menggunakan JSONAssert secara langsung?
Johannes
2
@ Johnannes: Hanya gaya.
kevinarpe
Sumber hamcrest-json saat ini memiliki tanggal komit terakhir 2012. Mungkin tidak lagi didukung dengan baik.
Thorbjørn Ravn Andersen
11

Anda dapat mencoba JsonUnit . Itu dapat membandingkan dua objek JSON dan melaporkan perbedaan. Itu dibangun di atas Jackson.

Sebagai contoh

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

Hasil dalam

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

Satu hal yang saya lakukan dan berfungsi dengan baik adalah membaca kedua objek ke dalam HashMap dan kemudian membandingkannya dengan assertEquals biasa (). Ini akan memanggil metode equals () dari hashmaps, yang akan secara rekursif membandingkan semua objek di dalamnya (mereka akan berupa hashmaps lain atau beberapa objek bernilai tunggal seperti string atau integer). Ini dilakukan dengan menggunakan parser Jackson JSON Codehaus '.

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

Pendekatan serupa dapat digunakan jika objek JSON adalah array.

Claudio Aguiar
sumber
6

Saya menggunakan ini, dan berfungsi dengan baik untuk saya (dengan 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;
        }
    }
}
penangkap
sumber
4

Untuk org.json saya telah meluncurkan solusi saya sendiri, sebuah metode yang membandingkan dengan instance JSONObject. Saya tidak bekerja dengan objek JSON kompleks dalam proyek itu, jadi saya tidak tahu apakah ini bekerja di semua skenario. Juga, mengingat bahwa saya menggunakan ini dalam unit test, saya tidak melakukan upaya optimasi. Ini dia:

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
sumber
1
Karena Anda menyebutkan optimasi :), jika val1nol, Anda akan mendapatkan NullPointerException dari kode iniif (!val1.equals(val2)) {
JohnDoDo
Itu terjadi pada yang terbaik dari kita juga :). +1 untuk memperbaikinya dalam jawaban Anda.
JohnDoDo
Poin diambil :) Berharap itu tidak mendapatkan terlalu banyak suara, kalau tidak akan banyak dukungan.
Victor Ionescu
1
Anda tidak menganggap jika js2ini nullatau tidak ketika js1tidaknull
Xiao
Kode ini tidak berfungsi untuk objek / urutan bersarang.
FabienB
3

Anda dapat menggunakan perpustakaan zjsonpatch , yang menyajikan informasi diff sesuai dengan RFC 6902 (JSON Patch). Sangat mudah digunakan. Silakan kunjungi halaman deskripsinya untuk penggunaannya

Gopi Vishwakarma
sumber
2

Saya akan mengambil perpustakaan di http://json.org/java/ , dan memodifikasi equalsmetode JSONObject dan JSONArray untuk melakukan tes kesetaraan yang mendalam. Untuk memastikan bahwa itu berfungsi tanpa menghiraukan urutan anak-anak, yang perlu Anda lakukan adalah mengganti peta bagian dalam dengan TreeMap, atau menggunakan sesuatu seperti Collections.sort().

Yoni
sumber
4
itu tidak terlalu bagus - itu benar-benar harus datang dengan kode untuk melakukan perbandingan json.
Chii
Tetapi bayangkan menulis kode itu di mana JSON dapat berupa apa saja dalam struktur apa pun ... tulis perbandingannya! Ini seperti menulis perbandingan untuk semua jenis halaman HTML.
JPM
2

Coba ini:

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;
    }
Misha
sumber
dalam jsonArrays ini mengembalikan true jika beberapa elemen bertepatan, sebagai lawan dari semua elemen bertepatan.
matiasg
@matiasg - if (obj1Array.length() != obj2Array.length())tidakkah semua elemen bertepatan?
kwah
3
@kwah: nggak. Pertimbangkan contoh ini: obj1Array = [1,1,1], obj2Array = [1,2,3]. Ini akan kembali benar. Juga, bahkan jika elemen bertepatan, mereka harus berada dalam urutan yang sama. Ini akan kembali benar untuk [1,2,3] dan [2,3,1] juga, yang salah
matiasg
2

Saya tahu ini biasanya dianggap hanya untuk pengujian tetapi Anda bisa menggunakan Hamcrest JSON comparitorSameJSONAs di Hamcrest JSON.

Hamcrest JSON SameJSONAs

Justin Ohms
sumber
2

Karate adalah apa yang Anda cari. Berikut ini sebuah contoh:

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

(penafian: dev di sini)

Peter Thomas
sumber
2

Untuk membandingkan jsons, saya sarankan menggunakan 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
sumber
0

Bagi mereka seperti saya yang ingin melakukan ini dengan Jackson, Anda dapat menggunakan unit json .

JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);

Kesalahan memberikan umpan balik yang bermanfaat tentang jenis ketidakcocokan:

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

Sepertinya tidak ada yang berfungsi dengan benar, jadi saya menulis ini:

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
sumber
0

Kode berikut akan lebih membantu untuk membandingkan dua JsonObject, JsonArray, JsonPrimitive dan 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
sumber
0

Melihat jawabannya, saya mencoba JSONAssert tetapi gagal. Jadi saya menggunakan Jackson dengan zjsonpatch. Saya memposting rincian dalam jawaban SO di sini .

likejudo
sumber
-5

Solusi ini bagi saya, kerja sangat bagus:

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

Semoga ini bisa membantu orang lain.

JLouis
sumber
tentu saja, letakkan saja nilai dan kondisi Anda, dan jenis pandangannya, dalam hal ini; Hashmap melalui listview.
JLouis
1
Ini adalah contoh yang bagus untuk bagaimana tidak melakukannya :)
Petr Újezdský