সেট রয়েছে এমন একটি সন্নিবেশ অর্ডার সংরক্ষণ তালিকা যা প্রয়োগ করে তালিকাও?


85

আমি একটি বাস্তবায়ন খুঁজে বের করার চেষ্টা করছি java.util.Listএবং java.util.Setজাভা একই সময়ে। আমি চাই এই শ্রেণিটি কেবল অনন্য উপাদানকে (যেমন Set) অনুমতি দেয় এবং তাদের ক্রমটি সংরক্ষণ করে (পছন্দ করে List)। এটি জেডিকে 6 তে বিদ্যমান?

এটি থাকা জরুরী List<T>#add(int, T)যাতে আমি একটি নির্দিষ্ট অবস্থানে প্রবেশ করতে পারি।


আপনি কি তাদের সন্নিবেশ ক্রম বা একটি দ্বারা সংজ্ঞায়িত কিছু ক্রম সংরক্ষণ করবেন Comparator? এছাড়াও আপনি কি Listইন্টারফেসের শব্দার্থবিদ্যাও চান ?

উত্তর:


208

TreeSetউপাদান ক্রম অনুসারে বাছাই করা হয়; LinkedHashSetসন্নিবেশ ক্রম ধরে রাখে। আশা করি এর মধ্যে একটি হ'ল আপনি যা পরেছিলেন।

আপনি উল্লেখ করেছেন যে আপনি একটি স্বেচ্ছাসেবী জায়গায় সন্নিবেশ করতে সক্ষম হতে চান , আমার সন্দেহ হয় আপনাকে নিজের লেখা লিখতে হবে - কেবল একটি HashSet<T>এবং একটি সমন্বিত একটি ক্লাস তৈরি করুন ArrayList<T>; কোনও আইটেম যুক্ত করার সময় তালিকায় যুক্ত করার আগে এটি সেটে রয়েছে কিনা তা পরীক্ষা করে দেখুন।

বিকল্পভাবে অ্যাপাচি এর কমন্স-কালেকশন 4 অফার ListOrderedSetএবং SetUniqueList, যা একই রকম আচরণ করে এবং প্রদত্ত প্রয়োজনীয়তাগুলি পূরণ করে should



12

আপনি কি মানে LinkedHashSet? এটি প্রবেশের ক্রম সংরক্ষণ করে, তবে সদৃশগুলিকে অনুমতি দেয় না।

আইএমএইচও, এটির একটি অস্বাভাবিক প্রয়োজন তবে আপনি নকল ছাড়াই একটি তালিকা লিখতে পারেন।

class SetList<T> extends ArrayList<T> {
    @Override
    public boolean add(T t) {
        return !super.contains(t) && super.add(t);
    }

    @Override
    public void add(int index, T element) {
        if (!super.contains(element)) super.add(index, element);
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            added |= add(t);
        return added;
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            if (!super.contains(t)) {
                super.add(index++, t);
                added = true;
            }
        return added;
    }
}

এটি Listইন্টারফেস বাস্তবায়ন করে না , প্রশ্নে আমার পরিবর্তনগুলি দেখুন
yegor256

4
stackoverflow.com/a/8185105/253468 দেখতে আরও ভাল দেখাচ্ছে কারণ এতে O(n)সন্নিবেশ জটিলতা নেই, ডাবল স্টোরেজ এবং sertোকানোO(log(n)) অপারেশনের মধ্যে একটি ট্রেড অফ রয়েছে ।
TWiStErRob

8

আপনি চুক্তি লঙ্ঘন ছাড়াই Listএবং Setএকবারে বাস্তবায়ন করতে পারবেন না । উদাহরণস্বরূপ, Set.hashCodeচুক্তিটি দেখুন:

কোনও সেটের হ্যাশ কোডটি সেটের উপাদানগুলির হ্যাশ কোডগুলির যোগফল হিসাবে সংজ্ঞায়িত হয়, যেখানে নাল উপাদানটির হ্যাশ কোডটি শূন্য হিসাবে সংজ্ঞায়িত করা হয়।

অন্যদিকে এখানে চুক্তিটি রয়েছে List.hashCode:

একটি তালিকার হ্যাশ কোডটি নিম্নলিখিত গণনার ফলাফল হিসাবে সংজ্ঞায়িত করা হয়েছে:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

সুতরাং একক শ্রেণি প্রয়োগ করা অসম্ভব যা উভয় চুক্তি সম্পাদনের গ্যারান্টি দেয়। equalsবাস্তবায়নের ক্ষেত্রে একই সমস্যা ।


4

আপনি নিজেকে জেডিকে 6-এ সীমাবদ্ধ না রাখলে আপনি অ্যাপাচি প্রচলিত সংগ্রহের লাইব্রেরি ব্যবহার করতে পারেন যা আপনার প্রয়োজনের জন্য যথাযথ মিলের প্রস্তাব দেয় - তালিকাআরডসেটসেট । এটি একত্রে পছন্দ Listএবং Setএকত্রিত :)


বিয়োগফল Listইন্টারফেস
ল্যাটারালফ্র্যাকাল

0

আমারও একই সমস্যা ছিল, তাই আমি নিজেই লিখেছি। এখানে দেখুন । IndexedArraySetপ্রসারিত ArrayListএবং কার্যকরী Set, তাই এটি সমস্ত কাজকর্মের যে আপনি প্রয়োজন সমর্থন করা উচিত। নোট করুন যে একটির মাঝখানে অবস্থানগুলিতে উপাদানগুলি সন্নিবেশ করা ArrayListবড় তালিকার জন্য ধীর হতে পারে কারণ নিম্নলিখিত সমস্ত উপাদানকে সরানো দরকার to আমার IndexedArraySetযে পরিবর্তন হয় না।


0

আর একটি বিকল্প (মাইনাস Listইন্টারফেসের প্রয়োজনীয়তা) হল পেয়ারা ImmutableSet, যা সন্নিবেশ ক্রম সংরক্ষণ করে। থেকে তাদের উইকি পাতা :

বাছাই করা সংগ্রহ ব্যতীত, আদেশের সময় নির্মাণের সময় থেকে সংরক্ষণ করা হয়। উদাহরণ স্বরূপ,

ImmutableSet.of("a", "b", "c", "a", "d", "b")

"এ", "বি", "সি", "ডি" ক্রমে এর উপাদানগুলির উপর পুনরাবৃত্তি হবে।

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