জাভাতে চাইল্ড অর্ডার উপেক্ষা করে সমতা জন্য দুটি JSON অবজেক্ট পরীক্ষা করা


233

আমি এমন একটি জেএসএন পার্সিং লাইব্রেরি খুঁজছি যা শিশু আদেশকে উপেক্ষা করে দুটি জেএসএন বস্তুর তুলনা সমর্থন করে, বিশেষত একটি ওয়েব পরিষেবা থেকে ফিরে আসা জেএসওএন ইউনিট পরীক্ষার জন্য supports

বড় কোন JSON গ্রন্থাগার এটি সমর্থন করে? Org.json গ্রন্থাগারটি কেবল একটি রেফারেন্স তুলনা করে।


1
উভয় বস্তু স্ট্রিং উপস্থাপনা এবং তুলনা সিরিয়ালাইজ করতে পারবেন না? আমি ধারণা করি যে সমস্ত লাইব্রেরি সমর্থন toString()করে বস্তুটিকে JSONস্ট্রিংয়ে রূপান্তর করতে to
তেজা কান্তমনেেনি

47
এটি ধরে নিয়েছে যে সিরিয়ালায়নের উপর এবং স্ট্রিং থেকে ক্রমটি সর্বদা একই থাকে। আমি এই ধারণাটি করতে স্বাচ্ছন্দ্যবোধ করি না।
জেফ

আপনি ঠিক জেফ, এটি মোটেই নিরাপদ নয়। এই পরীক্ষাটি এমন একটি দৃশ্য দেখায় যেখানে ম্যাপিংগুলি একই তবে টুস্ট্রিং () একই আউটপুট ফেরত দেয় না: gist.github.com/anonymous/5974797 । এর কারণ অন্তর্নিহিত হাশম্যাপটি বাড়তে পারে এবং আপনি কীগুলি সরিয়ে ফেললে, হ্যাশম্যাপ অভ্যন্তরীণ অ্যারে সঙ্কুচিত হয় না।
গিলিয়াম পেরেট

উত্তর:


84

একটি সাধারণ আর্কিটেকচারাল পয়েন্ট হিসাবে, আমি সাধারণত আপনার স্টোরেজ / নেটওয়ার্কিং স্তর ছাড়িয়ে নির্দিষ্ট সিরিয়ালাইজেশন ফর্ম্যাটের উপর নির্ভরতা ছাড়ার বিরুদ্ধে পরামর্শ দিই; এইভাবে, আমি প্রথমে আপনাকে সুপারিশ করব যে আপনি তাদের নিজের JSON প্রকাশের পরিবর্তে নিজের অ্যাপ্লিকেশন অবজেক্টের মধ্যে সমতা পরীক্ষা করার বিষয়টি বিবেচনা করুন।

এই কথাটি বলার পরে, আমি বর্তমানে জ্যাকসনের একটি বড় অনুরাগী যা তাদের অবজেক্টনোড.এক্কালস () বাস্তবায়নের আমার দ্রুত পঠন থেকে বোঝা যায় যে আপনি চাইছেন সেট সদস্যতার তুলনাটি করুন:

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

এই পদ্ধতিটি প্রতিসম নয়, কারণ এটি কেবলমাত্র শিশুদের 'সাবসেট' সম্পর্কের পরীক্ষা করে, সাম্যের নয়। 'অন্যান্য' অবজেক্টটির পরে শিশুদের মধ্যে আরও বেশি শিশু থাকতে পারে এবং এই পদ্ধতিটি এখনও সত্য হয়ে যাবে would
ইনি

23
@ যোনি: সত্য নয়, যেমন আকারের তুলনা রয়েছে। তাদের অবশ্যই একই বাচ্চাদের পাশাপাশি একই শিশুদের সংখ্যা থাকতে হবে। @ জলি রজার: এক্ষেত্রে, আমি জেএসএন থেকে কোনও পজোতে সিরিয়ালটিজ করছি না, তবে জেএসনকে এমন একটি সিস্টেম প্রেরণ করার সময় আমি যে একই প্রকারে পাঠিয়েছিলাম ঠিক তেমন ফর্ম্যাটে এটি ফেরত পাঠানোর উপর নির্ভর করতে পারি না এটা।
জেফ

1
@ জেফ এই কাজটি কি আপনার জন্য করেছে? জুনিটে, অ্যাসেটকুইলস আমার জন্য ব্যর্থ। প্রকল্পটি একটি পুরানো সংস্করণ (1.5) ব্যবহার করছে, fyi।
ronnyfm

1
আমি মনে করি আপনি জেএসওএনকে জোর না দিলে আপনি কিছু উচ্চ স্তরের পরীক্ষা নিখোঁজ করছেন। আপনার একটি পাতলা পরীক্ষা হতে পারে যা একটি http অনুরোধ করে এবং কিছু প্রত্যাশিত JSON এর সাথে প্রতিক্রিয়া জানায় - এটি ওয়েব পরিষেবার মূল কার্যকরী আচরণ।
মোগ্রোনালল

পারফরম্যান্স সম্পর্কিত কেবল একটি ছোট্ট নোট: 'মান' এর সাথে 'অন্যান্যভ্যালু'র সাথে তুলনা করা কোডটি যদি (মান.সেকালস (অন্যান্য.জিট (কী)) মিথ্যা প্রত্যাবর্তন করে; মান হিসাবে নালার গ্যারান্টিযুক্ত হয় তবে এটিকে সহজ করা যেতে পারে জসননোডের সমান () পদ্ধতির উচিত নালাগুলি যুক্তি গ্রহণ করা।
টিলম্যান

154

Skyscreamer করার চেষ্টা করুন JSONAssert

এর অ-কঠোর মোডের দুটি প্রধান সুবিধা রয়েছে যা এটিকে কম ভঙ্গুর করে তোলে:

  • অবজেক্ট এক্সটেনসিবিলিটি (উদাহরণস্বরূপ {আইডি: 1 of এর প্রত্যাশিত মান সহ , এটি এখনও পাস করবে: {আইডি: 1, মোরডেটা: 'x'} ।)
  • আলগা অ্যারে অর্ডারিং (উদাঃ ['কুকুর', 'বিড়াল'] == ['বিড়াল', 'কুকুর'])

কঠোর মোডে এটি json-lib এর পরীক্ষার শ্রেণীর মতো আচরণ করে।

একটি পরীক্ষা দেখতে এরকম কিছু দেখাচ্ছে:

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

JSONAssert.assertEquals মধ্যে পরামিতি () কলের হয় expectedJSONString , actualDataString এবং isStrict

ফলাফল বার্তাগুলি বেশ পরিষ্কার, যা সত্যিই বড় JSON অবজেক্টের সাথে তুলনা করার সময় গুরুত্বপূর্ণ।


18
আমি এই সমাধানটি ব্যবহার করছি, তবে আমি সবেমাত্র পেয়েছি যে আপনি নিজের পছন্দমতো একটি JSONCompareMode সরবরাহ করতে পারেন। যার মধ্যে একটি হ'ল NON_EXTENSIBLE। সুতরাং আপনার এর মতো কিছু থাকতে হবে: JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);NON_EXTENSIBLE মোডের অর্থ কোনও নতুন বা অনুপস্থিত ক্ষেত্র ব্যর্থতার কারণ, তবে অর্ডার দেয় না। মিথ্যা ব্যবহারের ফলে লেনিয়েন্ট মোড প্ররোচিত হবে যা কোনও অতিরিক্ত বা অনুপস্থিত শিশু উপাদানগুলির প্রতিবেদন করবে না।
ড্যান মন্দির

1
NON_EXTENSIBLE তুলনা মোড ঠিক আমি কি খুঁজছিলাম। এই জন্য ধন্যবাদ, ড্যান।
থটক্রাইম

আমি সমস্ত উত্সাহিত হওয়ার আগে: এই সমর্থনটি JSON অবজেক্ট এবং অ্যারেটিও বাসা বেঁধেছে? :)
খ্রিস্টান

2
লোকেরা গ্রন্থাগারটি ব্যবহারের আগে এই JSONassert ইস্যুকে বিবেচনায় নিতে চাইতে পারে : এটি নির্দেশ করে যে লাইব্রেরির নির্ভরতা নিয়ে বর্তমানে সম্ভাব্য লাইসেন্সিংয়ের সমস্যা রয়েছে।
চ্রিকি

3
JSONAssert ইস্যু # 44 পিআর 67-এ ক্লিন-রুম লাইব্রেরি প্রতিস্থাপনের সাথে স্থির হয়েছে, আজ JSONAssert 1.4.0 হিসাবে প্রকাশিত হয়েছে।
কার্টার পৃষ্ঠা

49

জিএসওএন ব্যবহার করে

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

সম্পাদনা করুন: যেহেতু GSON v2.8.6 উদাহরণস্বরূপ পদ্ধতিটি হ্রাসJsonParser.parse করা হয়েছে। আপনাকে স্থির পদ্ধতিটি ব্যবহার করতে হবে JsonParser.parseString:

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

আমার জন্য জিএসএন ২.৮.২ এ কাজ করে।
টম সালিবা

1
jsonArray উপাদানগুলি ক্রমযুক্ত না থাকলে এটি কাজ করছে না। সংস্করণ 2.8.2
নবীন কুমার আরবি

1
অবজেক্ট / উপাদানটির
ক্রমটি

এটি আমার পক্ষে কাজ করেছিল কারণ আমি এটি কেবলমাত্র ইউনিট পরীক্ষার জন্য চেয়েছিলাম যেখানে দুটি জসনের সম্পত্তিগুলির একই আদেশ ছিল
গ্যাব্রিয়েলবিবি

@ গ্যাব্রিয়েলবিবি আপনার প্রশ্নটি সম্পাদনা করে এআইপি কোন সংস্করণে অবনতি হয়েছে এবং কোন সংস্করণে কোডের নতুন স্টাইলটি কাজ করা শুরু করবে তা নির্দেশ করা উচিত।
স্বচ্ছলতা

30

আমি নিম্নলিখিতটি করতাম,

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

আপনি যদি জ্যাকসন ইতিমধ্যে ব্যবহার করছেন তবে এটি সেরা উত্তর আইএমএইচও।
ক্রিস্টোফ ডায়েজে

18
তবে এটি আমার মনে হয় একটি কঠোর তুলনা। এটি দুটি সমান জসনের উপাদানগুলির বিভিন্ন ক্রমযুক্ত হয়ে ফিরে আসবে।
ডেডপুল

@ ডেডপুল নীতিটি যথাযথ, আপনার আরও জড়িত থাকার তুলনায় আপনার তুলনা পরিবর্তন করতে হবে (গাছের সাধারণ সমানের চেয়ে উদাহরণের জন্য মূল ক্ষেত্রগুলি অনুসন্ধান করা)।
জেভেন্টিং

এটি সর্বকালের সেরা উত্তর। এটি কেবল এখন আমার প্রশ্নের উত্তর দেয় না, কারণ এটি আমাদের করা প্রায় প্রতিটি বস্তুর তুলনাও উত্তর দেয়। ধন্যবাদ, জোশু
লুইজ ফেইজিও ভেরোনেসি

2
@ ডেডপুল, এটি একটি কঠোর তুলনা হতে পারে, তবে এটি এখন কঠোর নয়।
আন্দ্রেই দামিয়ান-ফেকেতে

18

আপনি json-lib এর JSONAssert ক্লাসটি ব্যবহার করে দেখতে পারেন :

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

দেয়:

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

বা এমনকি সহজ: JSONAssert.assertJsonEquals ("{foo: 'বার', বাজ: 'qux'}", {foo: 'বার', বাজ: 'xyzzy'} ");
রব জুউরলিংক

2
এই সমাধানটি JSON এর মধ্যে ডেটা আইটেমগুলির ক্রমের জন্য কাজ করে তবে অ্যারেতে থাকা উপাদানগুলির ক্রমটি মেলে না তবে এটি ব্যর্থ হবে। যদি আপনার কোডটি এমন কোনও সেট ব্যবহার করে যা উদাহরণস্বরূপ JSON এ রূপান্তরিত হয়। নিম্নলিখিত JSON তুলনা ব্যর্থ হবে: JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }"); বার্তা সহ:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
ড্যান মন্দির

হ্যাঁ, এটি জসনের একটি সীমাবদ্ধতা :(। Json.org দেখায় যে কোনও আনর্ডারড কালেকশন টোকেন নেই {only কেবল মূল-মান জুড়ি ঘিরে ফেলতে পারে This এটি অত্যন্ত বিরক্তিকর
Merk

15

এই পাঠাগারটি ব্যবহার করুন: 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 - অ্যারেতে অর্ডার উপেক্ষা করে

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

আপনি কীভাবে আমরা এটি ব্যবহার করতে পারি তা আমি আরও পোষ্ট করতে পারি তবে এটি কীভাবে ব্যবহার করতে হয় তা বুঝতে আমাদের ডক প্রয়োজন
রান অ্যাডলার

নিশ্চিতভাবে ব্যবহার খুব সহজ: এটি আপনার পোমে যুক্ত করুন। <নির্ভরতা> <groupId> net.javacrumbs.json ইউনিট </ groupId> <artifactId> JSON ইউনিট </ artifactId> <version> '1.5.0 </ সংস্করণ> <সুযোগ> পরীক্ষা </ সুযোগ> </ নির্ভরতা>
চেথু

10x আমি লিঙ্কটিতে নির্দেশের দিকে নজর রেখেছি এবং এটি পেয়েছি :)
রান এডলার

12

আপনি যদি ইতিমধ্যে JUnit ব্যবহার করে থাকেন তবে সর্বশেষতম সংস্করণে এখন হ্যামক্রস্ট নিয়োগ করা হয়েছে। এটি একটি জেনেরিক মেলানো কাঠামো (বিশেষত ইউনিট পরীক্ষার জন্য কার্যকর) যা নতুন ম্যাথার তৈরি করতে বাড়ানো যেতে পারে।

hamcrest-jsonJSON- সচেতন ম্যাচগুলির সাথে একটি ছোট ওপেন সোর্স লাইব্রেরি রয়েছে । এটি ডকুমেন্টেড, পরীক্ষিত এবং সমর্থিত। নীচে কয়েকটি দরকারী লিঙ্ক রয়েছে:

জেএসএন লাইব্রেরি থেকে অবজেক্ট ব্যবহার করে কোড উদাহরণ org.json.simple:

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

Allyচ্ছিকভাবে, আপনি (1) "যে কোনও আদেশ" অ্যারে অনুমতি দিতে পারেন এবং (2) অতিরিক্ত ক্ষেত্র উপেক্ষা করতে পারেন।

যেহেতু (জাভা জন্য তাদেরকে JSON লাইব্রেরি বিভিন্ন আছে Jackson, GSON, json-lib, ইত্যাদি), এটা দরকারী যে hamcrest-jsonসমর্থন তাদেরকে JSON পাঠ্য (যেমন java.lang.String), ডগলাস Crockford এর তাদেরকে JSON লাইব্রেরি থেকে সেইসাথে নেটিভ সমর্থনকারী বস্তুর org.json

অবশেষে, আপনি JUnit ব্যবহার না করা হলে, আপনি সরাসরি দৃc়তার জন্য হ্যামক্রাস্ট ব্যবহার করতে পারেন। ( আমি এটি সম্পর্কে এখানে লিখেছি। )


সরাসরি JSONAssert ব্যবহার না করে হ্যামক্রাস্ট ম্যাচার ব্যবহার করার সুবিধা কী?
জোহানেস

2
@ জোহানেস: কেবল স্টাইল
কেভিনার্পে

হ্যামক্রেস্ট-জসন উত্সগুলির বর্তমানে শেষ প্রতিশ্রুতিবদ্ধ তারিখ 2012 রয়েছে It এটি এতটা ভাল সমর্থিত নাও হতে পারে।
থরবজর্ন রাভন অ্যান্ডারসন

11

আপনি JsonUnit চেষ্টা করতে পারেন । এটি দুটি জেএসএন বস্তুর তুলনা করতে পারে এবং পার্থক্যের প্রতিবেদন করতে পারে। এটি জ্যাকসনের উপরে নির্মিত হয়েছে।

উদাহরণ স্বরূপ

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

ফলাফল স্বরূপ

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

6

আমি যা করেছি এবং এটি আশ্চর্য কাজ করে সেগুলি হ্যাশম্যাপে উভয় বস্তু পড়তে হবে এবং তারপরে একটি নিয়মিত assertEquals () এর সাথে তুলনা করা। এটি হ্যাশম্যাপগুলির সমান () পদ্ধতিকে কল করবে, যা অভ্যন্তরের সমস্ত বস্তুর পুনরাবৃত্তির সাথে তুলনা করবে (তারা হয় অন্য হ্যাশম্যাপস বা স্ট্রিং বা পূর্ণসংখ্যার মতো কিছু একক মানের বস্তু)। কোডহাউসের জ্যাকসন জেএসন পার্সার ব্যবহার করে এটি করা হয়েছিল।

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

যদি JSON অবজেক্টের পরিবর্তে অ্যারে হয় তবে অনুরূপ পন্থা ব্যবহার করা যেতে পারে।


6

আমি এটি ব্যবহার করছি, এবং আমার জন্য ভাল কাজ করে (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

Org.json এর জন্য আমি নিজের সমাধানটি ঘটিয়েছি, একটি পদ্ধতি যা JSONObject উদাহরণগুলির সাথে তুলনা করে। আমি সেই প্রকল্পের জটিল জেএসএন বস্তুর সাথে কাজ করি নি, সুতরাং এটি সমস্ত পরিস্থিতিতে কাজ করে কিনা তা আমি জানি না। এছাড়াও, ইউনিট পরীক্ষায় আমি এটি ব্যবহার করে, আমি অপ্টিমাইজেশনে চেষ্টা করি নি। এটা এখানে:

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
যেহেতু আপনি অপ্টিমাইজেশনের কথা উল্লেখ করেছেন :), যদি val1নাল হয় তবে আপনি এই কোড থেকে একটি নালপয়েন্টার এক্সসেপশন পাবেনif (!val1.equals(val2)) {
জনডোডো

এটি আমাদের সেরাও ঘটে :) happens আপনার উত্তরে এটি ঠিক করার জন্য +1।
জনডোডো

পয়েন্ট নেওয়া :) আশা করি যদিও এটি খুব বেশি ভোট পাবে না, অন্যথায় এটি প্রচুর সমর্থন পাবে।
ভিক্টর আইনেস্কু

1
তাহলে আপনাকে বিবেচনা না js2হয় nullবা না যখন js1নয়null
জিয়াও

এই কোড নেস্টেড অবজেক্টস / সিকোয়েন্সগুলির জন্য কাজ করে না।
FabienB

3

আপনি zjsonpatch লাইব্রেরি ব্যবহার করতে পারেন , যা আরএফসি 6902 (জেএসএন প্যাচ) অনুসারে বিভিন্ন তথ্য উপস্থাপন করে। এটি ব্যবহার করা খুব সহজ। এটির ব্যবহারের জন্য দয়া করে এর বিবরণ পৃষ্ঠাটি দেখুন


2

আমি লাইব্রেরিটি http://json.org/java/equalsনিয়েছি এবং গভীর সমতা পরীক্ষা করতে JSONObject এবং JSONArray এর পদ্ধতিটি পরিবর্তন করেছি । এটি বাচ্চাদের ক্রম নির্বিশেষে কার্যকর হয় তা নিশ্চিত করার জন্য, আপনাকে যা করতে হবে তা হ'ল অভ্যন্তরীণ মানচিত্রটি একটি দ্বারা প্রতিস্থাপন করা TreeMapবা এর মতো কিছু ব্যবহার করা উচিত Collections.sort()


4
এটি এত দুর্দান্ত নয় - এটি জাসন তুলনা করার জন্য কোডের সাথে আসলেই আসা উচিত ছিল।
চিআই

তবে সেই কোডটি লিখতে কল্পনা করুন যেখানে JSON যে কোনও কাঠামোর যে কোনও কিছু হতে পারে ... তার তুলনা লিখুন! এটি সমস্ত প্রকারের HTML পৃষ্ঠাগুলির জন্য একটি তুলনা লেখার মতো।
জেপিএম

2

এটা চেষ্টা কর:

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

jsonArrays মধ্যে এই আয় যদি সত্য হয় কিছু উপাদানের কাকতালীয়ভাবে, যেমন উল্টোদিকে সব উপাদান কাকতালীয়ভাবে।
মাটিআসগ

@ মটিয়াস্গ - সমস্ত উপাদান মিলে if (obj1Array.length() != obj2Array.length())না তা নিশ্চিত করে না ?
কোওয়াহ

3
@ কেওয়াহ: নাহ এই উদাহরণটি বিবেচনা করুন: obj1 অ্যারে = [1,1,1], obj2 অ্যারে = [1,2,3]। এটি সত্য ফিরে আসবে। এছাড়াও, উপাদানগুলি একত্রিত হলেও, তাদের একই ক্রমে থাকা উচিত। এটি [1,2,3] এবং [2,3,1] এর ক্ষেত্রেও সত্য ফিরে আসবে, যা ভুল
matiasg

2

আমি জানি এটি সাধারণত পরীক্ষার জন্য বিবেচনা করা হয় তবে আপনি হ্যামকারেট জেএসওনে হ্যামকারেস্ট জেএসওন তুলনামূলক সামজেসোনাকে ব্যবহার করতে পারেন ।

হ্যামক্রেস্ট জেএসওন সমেজেসোনাস


2

কারাতে ঠিক আপনি যা খুঁজছেন তা হ'ল। এখানে একটি উদাহরণ:

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

(অস্বীকৃতি: দেব এখানে)


2

জসনগুলির তুলনা করার জন্য আমি জেএসএনকম্পিয়ার ব্যবহার করার পরামর্শ দিচ্ছি: 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

আমার মতো যারা জ্যাকসনের সাথে এটি করতে চান, আপনি জেসন -ইউনিট ব্যবহার করতে পারেন ।

JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);

ত্রুটিগুলি অমিলের ধরণ সম্পর্কে দরকারী প্রতিক্রিয়া দেয়:

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

0

অন্য কোনও কিছুই পুরোপুরি সঠিকভাবে কাজ করছে বলে মনে হচ্ছে না, তাই আমি এটি লিখেছিলাম:

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

নিম্নলিখিত কোড দুটি জসনঅবজেক্ট, জসনআরে, জসনপ্রিমিটিভ এবং জেসনলেটস এর সাথে তুলনা করতে আরও সহায়ক হবে।

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

উত্তরগুলি খুঁজছি, আমি জেএসওএনএসার্ট চেষ্টা করেছি কিন্তু এটি ব্যর্থ হয়েছিল। তাই আমি জ্যাকসনপ্যাচ সহ জ্যাকসনকে ব্যবহার করেছি। আমি এখানে এসও উত্তর বিবরণ পোস্ট ।


-5

আমার জন্য এই সমাধান, কাজের খুব ভাল:

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

আশা করি এটি অন্যকে সহায়তা করবে।


অবশ্যই, এই ক্ষেত্রে আপনার মান এবং শর্তগুলি এবং দৃষ্টিভঙ্গির ধরণ রাখুন; একটি তালিকা দর্শনের উপর হাশম্যাপ।
জে লুইস

1
এটি কীভাবে করবেন না তার জন্য এটি চমৎকার উদাহরণ :)
পেটর zjezdský ২ '
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.