জাভা সেটের জন্য কিছু 'রয়েছে'?


307

আমার একই ধরণের দুটি সেট, এ এবং বি রয়েছে।

আমাকে সেট B থেকে কোনও উপাদান রয়েছে কিনা তা আবিষ্কার করতে হবে A

সেটগুলির মাধ্যমে পুনরাবৃত্তি না করে কী করার সর্বোত্তম উপায় হতে পারে? সেট লাইব্রেরিতে রয়েছে contains(object)এবং আছে containsAll(collection), কিন্তু নেই containsAny(collection)


4
আপনি কি দক্ষতার কারণে বা কোড পরিষ্কারের জন্য পুনরাবৃত্তি এড়াতে চেষ্টা করছেন?
ysavit

উত্তর:


527

Collections.disjoint(A, B)কাজ করবে না ? ডকুমেন্টেশন থেকে:

রিটার্নস trueযদি দুইটি নির্দিষ্ট সংগ্রহের জন্য কমন কোনো উপাদান আছে।

সুতরাং, falseসংগ্রহটিতে যদি কোনও সাধারণ উপাদান থাকে তবে পদ্ধতিটি ফিরে আসে ।


17
এটি অন্যান্য সমাধানগুলিতে পছন্দ করুন কারণ এটি কোনও সেটকেই সংশোধন করে না বা একটি নতুন তৈরি করে না।
ডেভনসোল

7
এবং এটি স্ট্যান্ডার্ড জেআরই, এবং কেবল সেট নয়, কোনও সংগ্রহের সাথে কাজ করে।
পিয়েরে হেনরি

4
আমি মনে করি না এটি দ্রুততম, চৌরাস্তার প্রথম উপাদানটি পাওয়া গেলে এটি শর্ট সার্কিট হবে না।
বেন হর্নার

7
আসলে এটি প্রথম সাধারণ উপাদানটি খুঁজে পাওয়ার সাথে সাথে এটি শর্ট সার্কিট হবে
Xipo


156

Stream::anyMatch

জাভা 8 যেহেতু আপনি ব্যবহার করতে পারেন Stream::anyMatch

setA.stream().anyMatch(setB::contains)

1
আমি ঠিক এটিই খুঁজছিলাম! ধন্যবাদ :-) আমিও জানতাম না যে আপনি :: সিনট্যাক্সের সাহায্যে ভেরিয়েবল ব্যবহার করতে পারেন!
ড্যান্টিস্টন

1
@ পরিবর্তন, আপনি যে কোনও ম্যাচের ভিতরে কী ঘটতে পারেন তা ব্যাখ্যা করতে পারেন?
ক্রিশ্চিয়ানো

7
@ ক্রিশ্চিয়ানো এখানে, anyMatchসমস্ত উপাদান থেকে স্ট্রিম setAএবং তাদের setB.contains()সকলকে কল করবে। যদি কোনও উপাদানগুলির জন্য "সত্য" ফিরিয়ে দেওয়া হয়, সামগ্রিকভাবে এক্সপ্রেশনটি সত্যকে মূল্যায়ন করবে। আশা করি এটি সাহায্য করেছে।
অ্যালেক্স ভুলাজ


31

সেটগুলির জন্য রয়েছে কোনওগুলি প্রয়োগ করার একটি ভাল উপায় হ'ল পেয়ারা সেটস.ইনটারেসেকশন () ব্যবহার করা ।

containsAnyফিরে আসবে boolean, সুতরাং কলটি দেখে মনে হচ্ছে:

Sets.intersection(set1, set2).isEmpty()

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


3
এই পদ্ধতির ব্যবহারের একমাত্র অসুবিধা হ'ল আপনাকে পেয়ারা গ্রন্থাগারগুলি অন্তর্ভুক্ত করতে হবে। আমার মনে হয় যা অসুবিধা নয় কারণ গুগল সংগ্রহের এপিআইগুলি খুব শক্তিশালী।
মোহাম্মদ আদনান

@ ডিডিএরএল সহ বেশিরভাগ পেয়ারা সংগ্রহের ইউটিলিটি ফাংশন, ডেটা স্ট্রাকচারের ভিউ ফেরত দেয় । সুতরাং এই ক্ষেত্রে উদ্বিগ্ন হওয়ার জন্য কোনও "সেট বিল্ডিং" নেই। বাস্তবায়নটি এখানে পড়তে আগ্রহী এবং / অথবা জাভাদোকটি দেখুন: google.github.io/guava/releases/21.0/api/docs/com/google/common/…
চট

@ মোহাম্মদআদন্ন আরেকটি অসুবিধা হ'ল এটি সম্পূর্ণ ছেদটি গণনা করে - যদি সেট 1 এবং সেট 2 খুব বড় হয় তবে তাদের কোনও আইটেম মিল রয়েছে কিনা তা যাচাই করার চেয়ে এটি প্রচুর পরিমাণে রিসোর্স নিবিড় (সিপিইউ এবং মেমরি ওয়াইস উভয়) হবে।
মার্ক্সামা


16

আমি org.apache.commons.colferences.Cલેક્શન ইউটিস ব্যবহার করি

CollectionUtils.containsAny(someCollection1, someCollection2)

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

ব্যবহার করা সহজ, এবং ফাংশনের নামটি আরও পরামর্শমূলক।


5

retainAll()সেট ইন্টারফেসে ব্যবহার করুন। এই পদ্ধতিটি উভয় সেটে সাধারণ উপাদানগুলির একটি ছেদ সরবরাহ করে। আরও তথ্যের জন্য API ডক্স দেখুন।


যদি পুনরাবৃত্তি এড়ানোর বিষয়টি দক্ষতার জন্য হয় তবে retainAllসম্ভবত সাহায্য করবে না। AbstractCollectionপুনরাবৃত্তিতে এর বাস্তবায়ন ।
ysavit

1
ysavit সঠিক। প্রদত্ত ওপিটি উভয় সেটে কোনও উপাদান উপস্থিত রয়েছে কিনা তা সন্ধান করছে , একটি যথাযথ অ্যালগরিদম O(1)সবচেয়ে ভাল ক্ষেত্রে চলমান সময় retainAllথাকতে পারে , যেখানে একটির লাইনের সাথে কিছু থাকবে O(N)(এটি কেবলমাত্র 1 টি আকারের উপর নির্ভর করবে) সেরা ক্ষেত্রে চলমান সময়।
Zéychin

3

আমি HashMapসেট এ থেকে একটি তৈরি করার পরামর্শ দিচ্ছি , এবং তারপরে সেট বি এর মাধ্যমে পুনরাবৃত্তি করব এবং খ এর কোনও উপাদান এ এ আছে কিনা তা পরীক্ষা করে দেখি এটি O(|A|+|B|)সময় মতো চলবে (কারণ এতে কোনও সংঘর্ষ হবে না), সময়মতো retainAll(Collection<?> c)চালানো উচিত O(|A|*|B|)


3

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

A.removeAll(B)

এ সেটটি সংশোধন করবে। এই পরিস্থিতিতে মুছে ফেলা সমস্ত সত্য ফিরে আসবে (যেমন সরানো সমস্ত ডক্সে বর্ণিত )। তবে সম্ভবত আপনি এ সেটটি সংশোধন করতে চান না যাতে আপনি কোনও অনুলিপিটিতে এভাবে কাজ করার কথা ভাবতে পারেন:

new HashSet(A).removeAll(B)

এবং সেটগুলি পৃথক না হলে রিটার্নিংয়ের মানটি সত্য হবে, এটি হ'ল তাদের খালি খালি ছেদ রয়েছে।

আরো দেখুন এ্যাপাচি কমন্স সংগ্রহগুলি


2

আপনি ধরে রাখার সমস্ত পদ্ধতি ব্যবহার করতে পারেন এবং আপনার দুটি সেটের ছেদ পেতে পারেন ।


বেশিরভাগ ক্ষেত্রেই আসল সেটটি রাখা দরকার, সুতরাং retainAllএটি ব্যবহার করার জন্য মূল সেটটির একটি অনুলিপি তৈরি করা প্রয়োজন। তারপরে জাইচিনেরHashSet পরামর্শ মতো এটি ব্যবহার করা আরও দক্ষ ।
পেটর পুডলিক

এটি একটি রাষ্ট্র পরিবর্তন, শর্ত নয় যাচাই করুন
বেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.