জাভাতে দুটি স্ট্রিং সেট একত্রিত করার আরও ভাল উপায় কি?


90

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

Set<String> oldStringSet = getOldStringSet();
Set<String> newStringSet = getNewStringSet();

for(String currentString : oldStringSet)
{
    if (!newStringSet.contains(currentString))
    {
        newStringSet.add(currentString);
    }
}

উত্তর:


116

যেহেতু Setএকটিতে সদৃশ এন্ট্রি নেই, তাই আপনি দুটি দ্বারা একত্রিত করতে পারেন:

newStringSet.addAll(oldStringSet);

আপনি দু'বার জিনিস যুক্ত করলেও কিছু যায় আসে না, সেটটিতে কেবল একবার উপাদান থাকবে ... যেমন containsপদ্ধতি ব্যবহার করে এটি পরীক্ষা করার দরকার নেই check


88

আপনি এই ওয়ান-লাইনারটি ব্যবহার করে এটি করতে পারেন

Set<String> combined = Stream.concat(newStringSet.stream(), oldStringSet.stream())
        .collect(Collectors.toSet());

স্থির আমদানির সাথে এটি আরও সুন্দর দেখায় looks

Set<String> combined = concat(newStringSet.stream(), oldStringSet.stream())
        .collect(toSet());

অন্য উপায় হ'ল ফ্ল্যাটম্যাপ পদ্ধতিটি ব্যবহার করা :

Set<String> combined = Stream.of(newStringSet, oldStringSet).flatMap(Set::stream)
        .collect(toSet());

এছাড়াও যে কোনও সংগ্রহ সহজেই একটি একক উপাদানের সাথে একত্রিত হতে পারে

Set<String> combined = concat(newStringSet.stream(), Stream.of(singleValue))
        .collect(toSet());

এটি অ্যাডএলের চেয়ে কীভাবে ভাল?
KKlalala

7
@Klalala, আপনার প্রয়োজনীয়তা কোনটি আরও ভাল তা নির্ধারণ করবে। addAllস্ট্রিমগুলির ব্যবহার এবং ব্যবহারের মধ্যে প্রধান পার্থক্য হ'ল: • ব্যবহারের set1.addAll(set2)বিষয়বস্তু শারীরিকভাবে পরিবর্তনের পার্শ্ব প্রতিক্রিয়া ব্যবহার করবে set1। • তবে, স্ট্রীমগুলি ব্যবহারের ফলে সর্বদা Setদুটি সেটগুলির সামগ্রিক মূল সেট উদাহরণগুলির কোনও পরিবর্তন না করেই একটি নতুন দৃষ্টান্ত তৈরি হবে । আইএমএইচও এই উত্তরটি আরও ভাল কারণ এটি আসল প্রতিক্রিয়াগুলি প্রত্যাশা করে অন্য কোথাও যদি ব্যবহার করা হয় তবে এগুলি পার্শ্ব-প্রতিক্রিয়াগুলি এবং আসল সেটে অপ্রত্যাশিত পরিবর্তনের সম্ভাবনা এড়িয়ে চলে। এইচটিএইচ
এডওয়ার্ডসমেট

4
এতে অপরিবর্তনীয় সেটগুলিকে সমর্থন করার সুবিধাও রয়েছে। দেখুন: docs.oracle.com/javase/8/docs/api/java/util/...
edwardsmatt


12

সংজ্ঞা সেট থেকে কেবলমাত্র অনন্য উপাদান রয়েছে।

Set<String> distinct = new HashSet<String>(); 
 distinct.addAll(oldStringSet);
 distinct.addAll(newStringSet);

আপনার কোডটি বাড়ানোর জন্য আপনি তার জন্য একটি জেনেরিক পদ্ধতি তৈরি করতে পারেন

public static <T> Set<T> distinct(Collection<T>... lists) {
    Set<T> distinct = new HashSet<T>();

    for(Collection<T> list : lists) {
        distinct.addAll(list);
    }
    return distinct;
}

6

আপনি যদি পেয়ারা ব্যবহার করছেন তবে আরও নমনীয়তা পেতে আপনি কোনও বিল্ডারও ব্যবহার করতে পারেন:

ImmutableSet.<String>builder().addAll(someSet)
                              .addAll(anotherSet)
                              .add("A single string")
                              .build();

4

শুধু ব্যবহার newStringSet.addAll(oldStringSet)Setইতিমধ্যে বাস্তবায়ন এটি করায় সদৃশগুলি পরীক্ষা করার দরকার নেই ।



3
 newStringSet.addAll(oldStringSet);

এটি এস 1 এবং এস 2 এর ইউনিয়ন তৈরি করবে


2

ব্যবহার boolean addAll(Collection<? extends E> c)
করুন নির্দিষ্ট সংগ্রহের সমস্ত উপাদান এই সেটে যুক্ত করে যদি তারা ইতিমধ্যে উপস্থিত না থাকে (alচ্ছিক ক্রিয়াকলাপ)। যদি নির্দিষ্ট সংগ্রহটিও একটি সেট হয় তবে অ্যাডএল ক্রিয়াকলাপটি কার্যকরভাবে এই সেটটিকে সংশোধন করে যাতে এর মান দুটি সেটগুলির মিলন। অপারেশন চলমান অবস্থায় নির্দিষ্ট সংগ্রহটি সংশোধন করা হলে এই অপারেশনের আচরণ নির্ধারিত।

newStringSet.addAll(oldStringSet)

2

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

Set<String> newStringSet = getNewStringSet();
Set<String> oldStringSet = getOldStringSet();

Set<String> myResult;
if(oldStringSet.size() > newStringSet.size()){
    oldStringSet.addAll(newStringSet);
    myResult = oldStringSet;
} else{
    newStringSet.addAll(oldStringSet);
    myResult = newStringSet;
}

এইভাবে, যদি আপনার নতুন সেটে 10 টি উপাদান রয়েছে এবং আপনার পুরানো সেটে 100 000 রয়েছে, আপনি কেবল 100 000 এর পরিবর্তে 10 টি অপারেশন করবেন।


এটি একটি খুব ভাল যুক্তি যা আমি কল্পনাও করতে পারি না কেন এটি মূল অ্যাডএল পদ্ধতির পরামিতিগুলিতে নেই, যেমনpublic boolean addAll(int index, Collection<? extends E> c, boolean checkSizes)
গ্যাস্পার

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

হ্যাঁ, আমি বলছিলাম যে অন্য পদ্ধতিটি ওভারলোডিং
গ্যাসপাড়

2

আপনি যদি অ্যাপাচি কমন ব্যবহার করছেন তবে SetUtilsক্লাসটি ব্যবহার করুনorg.apache.commons.collections4.SetUtils;

SetUtils.union(setA, setB);

নোট করুন এটি একটি প্রদান করে SetView, যা অপরিবর্তনীয়।
jaco0646

2
Set.addAll()

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

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