দুটি ভিন্ন তালিকায় ঠিক একই উপাদান রয়েছে কিনা তা সন্ধান করার সহজ উপায়?


252

স্ট্যান্ডার্ড জাভা লাইব্রেরিতে দুটি তালিকায় ঠিক একই উপাদান রয়েছে কিনা তা খুঁজে পাওয়ার সহজ উপায় কী?

দুটি তালিকাগুলি একই উদাহরণ বা না তা বিচার্য নয় এবং তালিকার ধরণের পরামিতি আলাদা কিনা তা বিবেচ্য নয়।

যেমন

List list1
List<String> list2; 
// ... construct etc

list1.add("A");
list2.add("A"); 
// the function, given these two lists, should return true

আমি জানি এমন কিছু সম্ভবত আমার দিকে তাকিয়ে আছে :-)


সম্পাদনা: পরিষ্কার করার জন্য, আমি ক্রমে ঠিক একই উপাদান এবং উপাদানগুলির সংখ্যা খুঁজছিলাম।


উপাদানগুলি একই ক্রমে থাকতে হবে?
মাইকেল মায়ার্স

এটি আপনাকে কখনই প্রভাবিত করতে পারে না তবে সাবধান থাকুন যে হাইবারনেট
ধ্রুবক

উত্তর:


366

যদি আপনি অর্ডার সম্পর্কে চিন্তা করেন তবে কেবল সমান পদ্ধতিটি ব্যবহার করুন:

list1.equals(list2)

জাভাডোক থেকে:

সামঞ্জস্যের জন্য এই তালিকাটির সাথে নির্দিষ্ট বস্তুর তুলনা করুন। যদি নির্দিষ্ট অবজেক্টটিও একটি তালিকা হয় তবে কেবল এবং সত্যটি প্রত্যাবর্তন হয়, উভয় তালিকার একই আকার থাকে এবং দুটি তালিকার সমস্ত সংযুক্ত উপাদান সমান হয়। (দুটি উপাদান ই 1 এবং ই 2 সমান হয় যদি (e1 == নাল? E2 == নাল: e1.equals (e2))। অন্য কথায়, দুটি তালিকাকে একই ক্রমে একই উপাদানগুলি রাখলে সমান হিসাবে সংজ্ঞায়িত করা হয় । এই সংজ্ঞাটি নিশ্চিত করে যে সমান পদ্ধতিটি তালিকা ইন্টারফেসের বিভিন্ন বাস্তবায়নে সঠিকভাবে কাজ করে।

আপনি যদি অর্ডারকে স্বতন্ত্রভাবে চেক করতে চান তবে আপনি সমস্ত উপাদানগুলি সেটে অনুলিপি করতে পারবেন এবং ফলস্বরূপ সেটগুলিতে সমান ব্যবহার করতে পারেন:

public static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
    return new HashSet<>(list1).equals(new HashSet<>(list2));
}

এই পদ্ধতির একটি সীমাবদ্ধতা হ'ল এটি কেবল আদেশটিকে উপেক্ষা করে না, পাশাপাশি নকল উপাদানগুলির ফ্রিকোয়েন্সি। উদাহরণস্বরূপ, যদি list1["এ", "বি", "এ"] list2ছিল এবং ["এ", "বি", "বি"] Setপন্থাটি তাদের সমান হিসাবে বিবেচনা করবে।

আপনার যদি অর্ডার দিতে সংবেদনশীল হতে হবে তবে নকলের ফ্রিকোয়েন্সি সম্পর্কে সংবেদনশীল হতে পারেন তবে আপনি:


54
আপনি যদি অর্ডারের স্বতন্ত্র চেক করতে চান তবে আপনি কী কী সব ব্যবহার করতে পারবেন না?
ল্যাজ

6
সমস্ত ধারণাগুলির প্রয়োগের বিশদ সম্পর্কে আমি জানি না, তবে এটির মতো খারাপ লাগতে পারে বলে মনে হয়। যদি সমস্ত কলগুলিতে বার বার থাকে () থাকে তবে আপনার একটি ও (এন ^ 2) আলগ থাকবে। সেটগুলি সামগ্রিকভাবে O (nlogn) হওয়া উচিত
টম

6
প্রকৃতপক্ষে, যদি সেটগুলি কেবল ও (অলগন) হতে চলেছে, তবে অন্য পদ্ধতির তালিকাটিতে কালেকশন.সোর্ট () কল করুন এবং তারপরে সমান ব্যবহার করুন। আপনি যদি অর্ডারটি সংরক্ষণ করতে চান তবে আপনাকে তালিকাটি অনুলিপি করতে হবে এবং এটি ব্যয়বহুল হতে পারে এবং সেট সমাধানটির পক্ষে যেতে পারে ... সুতরাং আপনার নিজের পরিস্থিতিটি সম্পর্কে চিন্তা করতে হবে :-)।
টম

1
@ মিশিফার: আপনি কি সুপারিশ করছেন ও (এন ^ 2) আপনি সবচেয়ে ভাল করতে পারেন?
টম

8
@ ডেনিস মাপের পরীক্ষাটি কেবলমাত্র তখনই কাজ করে যদি আপনি জানেন যে প্রতিটি তালিকায় কেবলমাত্র স্বতন্ত্র উপাদান রয়েছে। উদাহরণস্বরূপ, প্রদত্ত a = [x, y, x]এবং b = [x, y, z]তারপরে মাপগুলি সমান এবং b.containsAll(a)সত্য ফিরে আসবে তবে bএতে একটি উপাদান নেই a
লরেন্স গনসাল্ভেস

95

আমি মন্তব্যগুলিতে একগুচ্ছ পদক্ষেপ পোস্ট করেছি বলে আমি মনে করি এটির নিজস্ব উত্তরের ওয়্যারেন্ট রয়েছে।

এখানে সবাই যেমন বলেছে, সমান () ব্যবহার করা অর্ডারের উপর নির্ভর করে। আপনি যদি অর্ডার সম্পর্কে চিন্তা না করেন তবে আপনার কাছে 3 টি বিকল্প রয়েছে।

বিকল্প 1

ব্যবহার containsAll()। এই বিকল্পটি আমার মতে আদর্শ নয়, কারণ এটি সবচেয়ে খারাপ ক্ষেত্রে পারফরম্যান্স দেয়, হে (এন ^ 2)।

বিকল্প 2

এর দুটি প্রকরণ রয়েছে:

2 ক) আপনি যদি আপনার তালিকার ক্রম বজায় রাখার বিষয়ে চিন্তা না করেন ... Collections.sort()উভয় তালিকায় ব্যবহার করুন। তারপরে ব্যবহার করুন equals()। এটি O (nlogn), কারণ আপনি দুটি ধরণের করেন এবং তারপরে একটি ও (এন) তুলনা।

2 খ) আপনার যদি তালিকাগুলির ক্রম বজায় রাখতে হয় তবে আপনি উভয় তালিকাকে প্রথমে অনুলিপি করতে পারেন। তারপরে আপনি অনুলিপি করা উভয় তালিকায় সমাধান 2a ব্যবহার করতে পারেন । তবে অনুলিপি করা হতে পারে যদি অনুলিপি করা খুব ব্যয়বহুল।

এটাও বিশালাকার:

বিকল্প 3

যদি আপনার প্রয়োজনীয়তা অংশ 2 বি সমান হয় তবে অনুলিপি করা খুব ব্যয়বহুল। আপনার জন্য বাছাই করতে আপনি একটি ট্রিসেট ব্যবহার করতে পারেন। প্রতিটি তালিকা তার নিজস্ব ট্রিসেটে ফেলে দিন। এটি সেটে সাজানো হবে এবং মূল তালিকাগুলি অক্ষত থাকবে। তারপরে equals()উভয়ের ক্ষেত্রে একটি তুলনা সম্পাদন করুন TreeSetTreeSetsS এ হে (nlogn) সময় নির্মিত হতে পারে, এবং equals()হে (ঢ) হয়।

তোমারটা নাও :-).

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


যদি আপনি সদৃশ সম্পর্কে যত্নশীল হন তবে আপনি সর্বদা পরীক্ষা করে দেখতে পারেন যে অন্য কোনও পরীক্ষার আগে সংগ্রহের আকার সমান।
ল্যাজ

আরও সুনির্দিষ্টভাবে, যদি সদৃশ থাকা অসমতার ইঙ্গিত দেয় তবে কোনও সমতা চেক সফল হওয়ার সুযোগ পাওয়ার আগে তালিকার আকার একই হওয়া উচিত।
ল্যাজ

7
@ ল্যাজ: দুটি তালিকায় বিভিন্ন উপাদান নকল করা থাকলে আকার পরীক্ষা করা কার্যকর হবে না। যেমন: [এ, এ, বি] বনাম [ক, খ, খ] সমান আকারের।
লরেন্স গনসাল্ভেস

@ লরেন্স: আমি সম্মত হই যে ল্যাজের পোস্টটি কিছুটা বিভ্রান্তিকর (এটি বোঝার আগে আমি এটি কয়েকবার পড়েছিলাম)। আমি এটি গ্রহণ করি যে যখন 2 শর্ত থাকে তখন তিনি বিশেষ ক্ষেত্রে "শর্টকাট" সরবরাহ করার চেষ্টা করছেন: (1) সদৃশ পদার্থ, এবং (2) তালিকার আকারগুলি পৃথক। আপনার উদাহরণে, আমি মনে করি লাজ এখনও বলছে যে আমরা আলোচনা করেছি এমন একই চেকগুলি করা প্রয়োজন। (কমপক্ষে আমি এটি পড়েছি)। যদি সদৃশগুলি কিছু যায় আসে না, তবে আপনি বিশেষ কেস চেক হিসাবে আকার ব্যবহার করতে পারবেন না। তবে যখন 2 শর্ত থাকে তখন আপনি কেবল "যদি (list1.size ()! = List2.size ()) মিথ্যা প্রত্যাবর্তন করতে বলতে পারেন;
টম

9
ধারণাগুলি সমস্তই আমার মনে হয় ভুল উত্তর দেবে, আপনাকে উভয় উপায়ে থাকতে হবে। a.containsAll(b) && b.containsAll(a)
রিচার্ড টিঙ্গল

24

যদি আপনি অ্যাপাচি কমন্স সংগ্রহগুলি ব্যবহার করছেন (বা ব্যবহার করতে খুশি হন) তবে আপনি কালেকশন Utils.isEqual Colલેક્શન ব্যবহার করতে পারেন যা "প্রদত্ত সংগ্রহগুলিতে ঠিক একই কার্ডিনালিটির সাথে একই উপাদান উপস্থিত থাকলে সত্য হয়"।


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

17

পার্টিতে খুব দেরি হয়ে গেছে তবে এই নাল নিরাপদ চেকটি যুক্ত করতে চেয়েছিলেন:

Objects.equals(list1, list2)

8

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

বলুন যে আপনার কাছে List<T>a এবং List<T>b আছে এবং আপনি নীচের শর্তগুলির সাথে সমান কিনা তা পরীক্ষা করতে চান:

1) ও (এন) প্রত্যাশিত চলমান সময়
2) সমতা হিসাবে সংজ্ঞায়িত করা হয়: ক বা খের সমস্ত উপাদানগুলির জন্য, উপাদানটি যে পরিমাণে সংঘটিত হয় তার সংখ্যার বিয়ের পরিমাণের বারের সমান equal এলিমেন্টের সাম্যতাটিকে T.equals () হিসাবে সংজ্ঞায়িত করা হয়

private boolean listsAreEquivelent(List<? extends Object> a, List<? extends Object> b) {
    if(a==null) {
        if(b==null) {
            //Here 2 null lists are equivelent. You may want to change this.
            return true;
        } else {
            return false;
        }
    }
    if(b==null) {
        return false;
    }
    Map<Object, Integer> tempMap = new HashMap<>();
    for(Object element : a) {
        Integer currentCount = tempMap.get(element);
        if(currentCount == null) {
            tempMap.put(element, 1);
        } else {
            tempMap.put(element, currentCount+1);
        }
    }
    for(Object element : b) {
        Integer currentCount = tempMap.get(element);
        if(currentCount == null) {
            return false;
        } else {
            tempMap.put(element, currentCount-1);
        }
    }
    for(Integer count : tempMap.values()) {
        if(count != 0) {
            return false;
        }
    }
    return true;
}

চলমান সময় হ'ল (এন) কারণ আমরা হ্যাশম্যাপে ও (2 * এন) সন্নিবেশগুলি করছি এবং ও (3 * এন) হ্যাশম্যাপ নির্বাচন করে। আমি এই কোডটি পুরোপুরি পরীক্ষা করে দেখিনি, তাই সাবধান হন :)

//Returns true:
listsAreEquivelent(Arrays.asList("A","A","B"),Arrays.asList("B","A","A"));
listsAreEquivelent(null,null);
//Returns false:
listsAreEquivelent(Arrays.asList("A","A","B"),Arrays.asList("B","A","B"));
listsAreEquivelent(Arrays.asList("A","A","B"),Arrays.asList("A","B"));
listsAreEquivelent(Arrays.asList("A","A","B"),null);

5

এই সংস্করণটি ব্যবহার করে দেখুন যার জন্য একই হতে পারে না তবে একই মানটির একাধিক হওয়া সমর্থন করে। এগুলি কেবল তখনই মিলবে যদি প্রত্যেকটির কোনও মানের সমান পরিমাণ থাকে।

public boolean arraysMatch(List<String> elements1, List<String> elements2) {
    // Optional quick test since size must match
    if (elements1.size() != elements2.size()) {
        return false;
    }
    List<String> work = newArrayList(elements2);
    for (String element : elements1) {
        if (!work.remove(element)) {
            return false;
        }
    }
    return work.isEmpty();
}

work.remove (উপাদান) হ'ল (n), সুতরাং এই সমাধানটি হ'ল (n ^ 2)
অ্যান্ড্রু

বা ও (এন 1 * এন 2) যা এর মতো সাজান
লি মায়াদোর

আমিও একই কৌশলটি ব্যবহার করেছি কারণ এটি সমস্ত পরিস্থিতি পরিচালনা করছে এবং সংগ্রহের আকারটি এত বড় নয় যে হে (এন ^ 2) গুরুত্বপূর্ণ নয়
নরেশ যোশি

3

তালিকার সমান পদ্ধতিটি এটি করবে, তালিকাগুলি অর্ডার করা হয়েছে, সুতরাং দুটি সমতুল্য হওয়ার জন্য একই তালিকায় একই উপাদান থাকতে হবে।

return list1.equals(list2);

3
তালিকাগুলি অর্ডার করা হয় না যতক্ষণ না আপনি সেগুলি সাজান।
মাইকেল মায়ার্স

@ নিজেকে দীর্ঘশ্বাস। এমন সুস্পষ্ট উত্তর। আপনি জানেন যে এটি অনেক দিন হয়ে গেছে যখন আপনি কোনও ওয়েব পৃষ্ঠা আর Ctrl + F করতেও পারবেন না। :)
গ্রুন্ডলেফ্লেক

2
@mmyers: ITEMS মধ্যে তালিকা যদি না আপনি সাজানোর আদেশ নেই তাদের। তালিকাগুলিতে তাদের আইটেমগুলির একটি অন্তর্নিহিত ক্রম রয়েছে (সূচক অনুসারে), যা আপনি তালিকার আইটেমগুলি পরিবর্তন না করে পরিবর্তন করবেন না। (বনাম। সেট বা সংগ্রহগুলি যেখানে আপনি যদি সেগুলির মাধ্যমে দু'বার পুনরাবৃত্তি করেন তবে ধারাবাহিক অর্ডার দেওয়ার গ্যারান্টি নেই)
জেসন এস

আমি মনে করি যে দ্যাভ বলতে তালিকাগুলি অর্ডার করার অর্থ কী তা হল তালিকাগুলি সমতা নির্ধারণের জন্য উপাদানগুলির ক্রমটি বিবেচনা করে। জাভাদোক দেখুন।
ল্যাজ

2
আমার অর্থ হ'ল list "এ", "বি" containing এবং "{" বি "," এ "} সমন্বিত একটি তালিকা এই পদ্ধতির সাথে অসম হবে। এটি উদ্দেশ্যমূলকভাবে খুব সম্ভবত হতে পারে তবে আমি এটি নিশ্চিত করতে চেয়েছিলাম যে কেউ এটি উপেক্ষা করছে না।
মাইকেল মায়ার্স

3

দুটি তালিকার ক্ষেত্রে একই উপাদান থাকলেও ভিন্ন ক্রমের ক্ষেত্রে সমাধান:

public boolean isDifferentLists(List<Integer> listOne, List<Integer> listTwo) {
    if(isNullLists(listOne, listTwo)) {
        return false;
    }

    if (hasDifferentSize(listOne, listTwo)) {
        return true;
    }

    List<Integer> listOneCopy = Lists.newArrayList(listOne);
    List<Integer> listTwoCopy = Lists.newArrayList(listTwo);
    listOneCopy.removeAll(listTwoCopy);

    return CollectionUtils.isNotEmpty(listOneCopy);
}

private boolean isNullLists(List<Integer> listOne, List<Integer> listTwo) {
    return listOne == null && listTwo == null;
}

private boolean hasDifferentSize(List<Integer> listOne, List<Integer> listTwo) {
    return (listOne == null && listTwo != null) || (listOne != null && listTwo == null) || (listOne.size() != listTwo.size());
}

2
আমি মনে করি আপনার দুটি তালিকা অনুলিপি করার দরকার নেই।
অজাহানচারেলস

1
আপনি কেন এটি removeAll()পরিবর্তে ব্যবহার করেছেন তা নোট করতে পারেন containsAll()(আমার বোধগম্যতা হল যে তালিকার দুটিতে যদি ডুপ্লিকেট থাকে কেবলমাত্র তালিকায় একবারে অন্তর্ভুক্ত থাকে তবে সমস্তগুলি () পদ্ধতির তালিকাগুলিকে ভুল হিসাবে সমান হিসাবে রিপোর্ট করবে)।
অজাহানচার্লস

3

টম এর উত্তর দুর্দান্ত আমি তার উত্তর সাথে সম্পূর্ণ সম্মত!

এই প্রশ্নের একটি আকর্ষণীয় দিক হ'ল, আপনার Listনিজের ধরণের এবং এর অন্তর্নিহিত ক্রমটি প্রয়োজন কিনা ।

যদি না হয় আপনি হ্রাস করতে পারেন Iterableবা Collectionযা আপনাকে চেক করতে চান না তার চেয়ে সন্নিবেশের সময় সাজানো এমন ডেটা স্ট্রাকচারের চারপাশে যাওয়ার কিছুটা নমনীয়তা দেয়।

আদেশটি কখনই গুরুত্ব দেয় না (এবং আপনার সদৃশ উপাদান নেই) ব্যবহার করে বিবেচনা করুন Set

যদি অর্ডারটি গুরুত্বপূর্ণ হয় তবে সন্নিবেশের সময় দ্বারা সংজ্ঞায়িত হয় (এবং আপনার সদৃশ নেই) LinkedHashSetএকটি ট্রিসেটের মতো যা বিবেচনা করে তবে সন্নিবেশের সময় দ্বারা আদেশ করা হয় (নকলগুলি গণনা করা হয় না)। এটি আপনাকে O(1)মোড়কবিহীন অ্যাক্সেস দেয় O(log n)


2

কোডের উদাহরণ:

public static '<'T'>' boolean isListDifferent(List'<'T'>' previousList,
        List'<'T'>' newList) {

    int sizePrevoisList = -1;
    int sizeNewList = -1;

    if (previousList != null && !previousList.isEmpty()) {
        sizePrevoisList = previousList.size();
    }
    if (newList != null && !newList.isEmpty()) {
        sizeNewList = newList.size();
    }

    if ((sizePrevoisList == -1) && (sizeNewList == -1)) {
        return false;
    }

    if (sizeNewList != sizePrevoisList) {
        return true;
    }

    List n_prevois = new ArrayList(previousList);
    List n_new = new ArrayList(newList);

    try {
        Collections.sort(n_prevois);
        Collections.sort(n_new);
    } catch (ClassCastException exp) {
        return true;
    }

    for (int i = 0; i < sizeNewList; i++) {
        Object obj_prevois = n_prevois.get(i);
        Object obj_new = n_new.get(i);
        if (obj_new.equals(obj_prevois)) {
            // Object are same
        } else {
            return true;
        }
    }

    return false;
}

2

লরেন্সের উত্তর ছাড়াও, আপনি যদি এটিকে নাল-নিরাপদ করতে চান তবে:

private static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
    if (list1 == null)
        return list2==null;
    if (list2 == null)
        return list1 == null;
    return new HashSet<>(list1).equals(new HashSet<>(list2));
}

1
আপনি চেকগুলি সহজ করতে পারেন:if (list1 == null) return list2==null; if (list2 == null) return false;
Xerus

তালিকাগুলি যদি [ক, ক, খ, সি] এবং [ক, খ, সি] হয় তবে কাজ করে না এবং তালিকাগুলির আকার একই হয় তা নিশ্চিত করার জন্য অতিরিক্ত চেক যোগ না করা পর্যন্ত সত্য ফিরে আসবে।
ভেঙ্কট মাধব

2
list1.equals(list2);

যদি আপনার তালিকায় একটি কাস্টম ক্লাস মাইক্লাস থাকে তবে এই শ্রেণিটি অবশ্যই equalsফাংশনটিকে ওভাররাইড করে ।

 class MyClass
  {
  int field=0;
  @0verride
  public boolean equals(Object other)
        {
        if(this==other) return true;
        if(other==null || !(other instanceof MyClass)) return false;
        return this.field== MyClass.class.cast(other).field;
        }
  }

দ্রষ্টব্য: আপনি যদি একটি এর পরিবর্তে java.util.Set এর সমান পরীক্ষা করতে চান java.util.Listতবে আপনার অবজেক্টটি অবশ্যই hashCode ফাংশনটিকে ওভাররাইড করে ।


1
লাইনটি করা উচিত: এইটি ফিরিয়ে দিন field ক্ষেত্রটি == মাইক্র্লাস.class.cast (অন্যান্য); be this.field == MyClass.class.cast (অন্যান্য)। ফিল্ড ফেরত দিন;
আলপায়ার

ওহ! তুমি ঠিক বলছো ! আমি এটা ঠিক করতে চলেছি। ধন্যবাদ!
পিয়েরে


0

: আপনি এ্যাপাচি এর org.apache.commons.collections গ্রন্থাগার ব্যবহার করতে পারেন http://commons.apache.org/collections/apidocs/org/apache/commons/collections/ListUtils.html

public static boolean isEqualList(java.util.Collection list1,
                              java.util.Collection list2)

এটির জন্য তালিকার উপাদানগুলি একই ক্রমে থাকা প্রয়োজন।
জোশ-কেইন

আপনি তুলনা করার আগে তালিকাটি বাছাই করতে পারেন
ডেভিড ঝাও

অবশ্যই, আপনি তালিকায় সঞ্চিত ধরণের বা বাছাইযোগ্য (বা আপনার সাথে একটি তুলনামূলক সেট আপ করেছেন) প্রদান করতে পারেন। তবে অ্যাপাচি বাস্তবায়ন অ্যালগরিদম স্থির হওয়া ব্যতীত নিয়মিত তালিকা 1.Equals (list2) এর চেয়ে আলাদা নয়। আমি দেখতে পাচ্ছি যেখানে আমি প্রশ্নটি ভুল বুঝেছিলাম এবং এটি একই ক্রমে তালিকার আইটেমগুলির তুলনা করতে জিজ্ঞাসা করছে। আমার খারাপ!
জোশ-কেইন

@ ডেভিডজাও: লিঙ্কটি মারা গেছে।
অনিকেত কুলকারনী


0

উভয় তালিকাগুলি নাল নয় তা পরীক্ষা করুন। যদি তাদের আকারগুলি পৃথক হয়, তবে এই তালিকাগুলি সমান নয়। কীগুলির তালিকা হিসাবে তালিকার উপাদানগুলিকে এবং মান হিসাবে তাদের পুনরাবৃত্তি সমন্বিত মানচিত্র তৈরি করুন এবং মানচিত্রের তুলনা করুন।

অনুমান, উভয় তালিকাগুলি যদি নাল হয় তবে আমি তাদের সমান মনে করি।

private boolean compareLists(List<?> l1, List<?> l2) {
    if (l1 == null && l2 == null) {
        return true;
    } else if (l1 == null || l2 == null) {
        return false;
    }

    if (l1.size() != l2.size()) {
        return false;
    }

    Map<?, Integer> m1 = toMap(l1);
    Map<?, Integer> m2 = toMap(l2);

    return m1.equals(m2);
}

private Map<Object, Integer> toMap(List<?> list) {
    //Effective size, not to resize in the future.
    int mapSize = (int) (list.size() / 0.75 + 1);
    Map<Object, Integer> map = new HashMap<>(mapSize);

    for (Object o : list) {
        Integer count = map.get(o);
        if (count == null) {
            map.put(o, 1);
        } else {
            map.put(o, ++count);
        }
    }

    System.out.println(map);
    return map;
}

দয়া করে নোট করুন, পদ্ধতির সমানগুলি এই বিষয়গুলির জন্য সঠিকভাবে সংজ্ঞায়িত করা উচিত। https://stackoverflow.com/a/24814634/4587961


1
আপনি ধরে নিয়েছেন যে কোনও উপাদান প্রতিটি তালিকায় বিভিন্ন সময় বিভিন্ন উপস্থাপন করতে পারে না যেমন [x, x, y]বনাম [x, y, y]আপনার বাস্তবায়নের মাধ্যমে সত্য হয়ে উঠবে।
অজাহানচার্লস

@ কোডকনফিডেন্ট, আপনাকে অনেক ধন্যবাদ! আমি উত্তর আপডেট। আমি মাও ব্যবহার করব!
ইয়ান খোন্সকি

-2

এটি নির্ভর করে আপনি কোন কংক্রিট তালিকার শ্রেণিটি ব্যবহার করছেন। বিমূর্ত শ্রেণীর অ্যাবস্ট্রাক্ট কালেকশনের একটি পদ্ধতি রয়েছে কন্টেলস অল (সংগ্রহ) নামে একটি পদ্ধতি রয়েছে যা অন্য সংগ্রহ সংগ্রহ করে (একটি তালিকা একটি সংগ্রহ) এবং:

যদি এই সংগ্রহে নির্দিষ্ট সংগ্রহের সমস্ত উপাদান থাকে তবে সত্যটি ফেরত দেয়।

সুতরাং যদি কোনও অ্যারেলিস্ট পাস করা হয় তবে আপনি এই পদ্ধতিটি কল করতে পারেন যে তারা ঠিক একই কিনা।

       List foo = new ArrayList();
    List bar = new ArrayList();
    String str = "foobar";

    foo.add(str);
    bar.add(str);

    foo.containsAll(bar);

সমস্ত () অন্তর্ভুক্ত হওয়ার কারণ হ'ল এটি দ্বিতীয় তালিকার সাথে ম্যাচের সন্ধানের জন্য প্রথম তালিকার মধ্য দিয়ে পুনরাবৃত্তি করে। সুতরাং তারা যদি অর্ডার থেকে সমান হয় () এটি গ্রহণ করবে না।

সম্পাদনা: আমি এখানে একটি বিকল্প দিতে চাই অফার করা বিভিন্ন অপশন সম্পাদনের amorised চলমান সময় সম্পর্কে। রানিং সময় কি গুরুত্বপূর্ণ? অবশ্যই। এটা কি আপনার একমাত্র বিষয় বিবেচনা করা উচিত? না।

আপনার তালিকাগুলি থেকে প্রত্যেকটি একক উপাদানকে অন্য তালিকাগুলিতে অনুলিপি করতে ব্যয় করতে সময় লাগে এবং এটি মেমরির একটি ভাল অংশও গ্রহণ করে (কার্যকরভাবে আপনি যে স্মৃতি ব্যবহার করছেন তার দ্বিগুণ করে)।

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

আমার চূড়ান্ত পরামর্শ? আপনার ডেটা সেট এবং আপনার ডেটা সেটে আপনার কতগুলি উপাদান রয়েছে তা বিবেচনা করা দরকার এবং আপনি এখানে একটি ভাল সিদ্ধান্ত নেওয়ার আগে আপনার ডেটা সেটে প্রতিটি বস্তু কত বড় large তাদের সাথে চারপাশে খেলুন, প্রতিটি উপায়ে একটি তৈরি করুন এবং দেখুন কোনটি দ্রুত চলে। এটি একটি ভাল অনুশীলন।


2
এটি foo.containsAll (বার) এবং & বার.contains All (foo) হতে হবে না; ?
কার্ল ম্যানাস্টার

না, এটি foo এর প্রতিটি উপাদান দিয়ে যায় এবং বারে সেই উপাদানটি রয়েছে কিনা তা দেখে। এরপরে এটি নিশ্চিত করে যে দৈর্ঘ্য দুটি তালিকার সমান। প্রতিটি foo- এর জন্য যদি বারে একটি উপাদান থাকে যেমন foo.element == bar.element এবং foo.length == bar.length তবে সেগুলিতে একই উপাদান রয়েছে।
amischiefr

দক্ষতার গ্যারান্টি আছে কিনা তা কি আমরা জানি? বা এটি সাধারণত ও (এন ^ 2) হয়?
টম

ম্যাচের উপাদানগুলির সন্ধানের মাধ্যমে পুনরাবৃত্তি হওয়া অন্য কোনও অ্যারের মতো সবচেয়ে খারাপ ক্ষেত্রে চলমান সময় ও (এন ^ 2) হতে চলেছে। এই ক্ষেত্রে, দেখে মনে হচ্ছে বাস্তবায়নটি ম্যাচের সন্ধানের জন্য একবারে একটি উপাদান দিয়ে পুনরাবৃত্তি করছে। Amorised চলমান সময় সম্পর্কে আমি অনুমান করব না, তবে হ্যাঁ সবচেয়ে খারাপ পরিস্থিতি হে (এন ^ 2)।
amischiefr

1
এটি কাজ করে না: {1,2,2}। কন্টেন্টস সব ({1,1,2}) এবং উপ-পদ্য এবং দুটি তালিকার আকার একই।
কমকো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.