জাভাতে অর্ডার সেট এর কোন বাস্তবায়ন?


103

যদি কেহ উদ্দেশ্য সি সাথে পরিচিত সেখানে একটি সংগ্রহ বলা হয় NSOrderedSetযে হিসাবে কাজ সেট এবং তার আইটেম একটি হিসাবে অ্যাক্সেস করা যেতে পারে এরে এর বেশী।

জাভাতে কি এরকম কিছু আছে?

শুনেছি সেখানে একটি সংগ্রহ রয়েছে বলা হয়েছে LinkedHashMap, তবে সেটগুলির মতো আমি এর মতো কিছু পাইনি।


আমি সি ++ তে একই ধরণের সমস্যায় কাজ করছি। এনএসআরআরডসেটের সাহায্যে, আমরা এতে orderোকানো ক্রমে উপাদানগুলি অ্যাক্সেস করতে পারি?
বিনয়

আপনি কি জানেন যে সি ++ এ কীভাবে উপরের কার্যকারিতাটি পাবেন? আমি, ই এসইটি হিসাবে অভিনয় করছি এবং অ্যারের উপাদান হিসাবে অ্যাক্সেস করা যেতে পারে?
বিনয়

উত্তর:


124

লিঙ্কডহ্যাশসেট ক্লাসটি একবার দেখুন

জাভা ডক থেকে :

পূর্বাভাসযোগ্য পুনরাবৃত্তির ক্রম সহ হ্যাশ টেবিল এবং সেট ইন্টারফেসের লিঙ্কযুক্ত তালিকা বাস্তবায়ন । এই প্রয়োগটি হ্যাশসেট থেকে পৃথক হয়েছে কারণ এটি তার সমস্ত এন্ট্রি দিয়ে দ্বিগুণ-লিঙ্কযুক্ত তালিকা বজায় রাখে। এই লিঙ্কযুক্ত তালিকাটি পুনরাবৃত্তির ক্রম সংজ্ঞায়িত করে, এটি সেই ক্রম যা উপাদানগুলিকে সেটে প্রবেশ করানো হয়েছিল (সন্নিবেশ-ক্রম)নোট করুন যে কোনও উপাদানটি যদি সেটে পুনরায় .োকানো হয় তবে সন্নিবেশ ক্রমটি প্রভাবিত হবে না । (একটি উপাদান ই একটি সেটগুলিতে পুনরায় সজ্জিত করা হয় যদি s.add (e) শুরু করা হয় যখন s.contains (e) প্রার্থনার পূর্বে অবিলম্বে সত্য ফিরে আসবে।)


আপনাকে অনেক ধন্যবাদ. এটিকে তুচ্ছ দেখাতে LinkedHashMapদেখায় তবে আমি এটি কোনওভাবে খুঁজে পাইনি।
উকো


33

প্রতিটি সেটে একটি পুনরাবৃত্তি রয়েছে ()। একটি স্বাভাবিক HashSet পুনরুক্তিকারীর বেশ র্যান্ডম একটি TreeSet সাজানোর ক্রম, একটি দ্বারা এটা আছে যে, LinkedHashSet পুনরুক্তিকারীর সন্নিবেশ আদেশ দ্বারা iterates।

তবে আপনি কোনও লিঙ্কডহ্যাশসেটে কোনও উপাদান প্রতিস্থাপন করতে পারবেন না। আপনি একটি মুছে ফেলতে এবং অন্যটিকে যুক্ত করতে পারেন, তবে নতুন উপাদানটি আসল জায়গায় থাকবে না। লিংকডহ্যাশম্যাপে আপনি বিদ্যমান কীটির জন্য একটি মান প্রতিস্থাপন করতে পারেন এবং তারপরে মানগুলি মূল ক্রমে থাকবে।

এছাড়াও, আপনি একটি নির্দিষ্ট অবস্থানে সন্নিবেশ করতে পারবেন না।

সদৃশ avoidোকানো এড়াতে আপনি একটি সুস্পষ্ট চেক সহ আরও একটি অ্যারেলিস্ট ব্যবহার করতে পারেন।


আমি নির্দিষ্ট অবস্থানের উপর উপাদান সেট করতে / পেতে সক্ষম হতে চাই এবং আদেশ দিয়ে আমি তাদের যুক্ত করেছি সেগুলি পেতে। এটি যে করা LinkedHashSetউচিত seams । উত্তরের জন্য ধন্যবাদ
ইউকো 3'12

12

কটাক্ষপাত জাভা মান এপিআই ডক । ঠিক পাশেই LinkedHashMap, একটি আছে LinkedHashSet। তবে মনে রাখবেন যে সেগুলিতে ক্রমটি সন্নিবেশ আদেশ, উপাদানগুলির প্রাকৃতিক ক্রম নয়। এবং আপনি কেবল সেই ক্রমে পুনরাবৃত্তি করতে পারেন, এলোমেলো অ্যাক্সেস করবেন না (পুনরাবৃত্তির পদক্ষেপ গণনা ব্যতীত)।

এছাড়া একটি ইন্টারফেস SortedSetদ্বারা বাস্তবায়িত TreeSetএবং ConcurrentSkipListSet। উভয়ই তাদের উপাদানগুলির প্রাকৃতিক ক্রমে পুনরাবৃত্তির অনুমতি দেয় বা এ Comparator, তবে এলোমেলো অ্যাক্সেস বা সন্নিবেশ ক্রমের নয়।

এমন একটি ডেটা স্ট্রাকচারের জন্য যা উভয় সূচকে দক্ষ অ্যাক্সেস পেয়েছে এবং সেটটি মানদণ্ডকে দক্ষতার সাথে প্রয়োগ করতে পারে, আপনার এড়িয়ে যাওয়ার একটি তালিকা দরকার , তবে জাভা স্ট্যান্ডার্ড এপিআইতে সেই কার্যকারিতা সহ কোনও প্রয়োগ করা হয়নি, যদিও আমি নিশ্চিত যে এটির সন্ধান করা সহজ though ইন্টারনেটে.


আমি আপনার মন্তব্যে ভুল বোঝাবুঝি করছি তবে আমি এই ধারণাটির মধ্যে ছিলাম যে জাভা ১.6 থেকে স্কিপ তালিকার উপর ভিত্তি করে বেশ কয়েকটি ডিফল্ট সংগ্রহ রয়েছে (যেমন, বলুন, কনকন্ট্রালস্কিপলিস্ট সেট ইত্যাদি)।
ট্যাকটিক্যাল কোডার

@ ইউজার ৯৮৮০৫২: হ্যাঁ, তবে তারা সূচক দ্বারা এলোমেলো অ্যাক্সেস বাস্তবায়ন করে না (যদিও আমার এড়িয়ে চলা তালিকা সম্পর্কে এটি বোঝা উচিত যে এটি সম্ভব হওয়া উচিত), যা ইউকো যা চায় তা মনে হয়।
মাইকেল বর্গওয়ার্ট

@ মিশেলবার্গওয়ার্ড জাভা 6 এবং এর পরে স্কিপ লিস্টের বাস্তবায়নগুলির একটি জুড়ি রয়েছে: ConcurrentSkipListMapএবং ConcurrentSkipListSet। উভয়ই প্রাকৃতিক অর্ডার বা তুলনাকারীর ভিত্তিতে বাছাই করে। আপনারা আলোচিত এলোমেলো অ্যাক্সেস বা প্রবেশের আদেশ-প্রদান করেছেন কিনা তা আমি বুঝতে পারি না।
তুলসী বার্ক

@ বাসিলবার্ক: ভাল সন্ধান, এবং সম্পাদনার জন্য ধন্যবাদ। ওপি সূচকের মাধ্যমে অ্যাক্সেস চেয়েছিল, এবং এখন আমি এটির দিকে তাকিয়ে এটি সম্পর্কে চিন্তা করেছি বলে মনে করি, বাদ দেওয়া তালিকাগুলি আসলে তেমন ক্ষমতাও রাখে না ...
মাইকেল বর্গওয়ার্ট

5

java.util.TreeSetযে সরঞ্জাম ব্যবহার করে দেখুন SortedSet

দস্তাবেজের উদ্ধৃতি দিতে:

"উপাদানগুলি তাদের প্রাকৃতিক ক্রম ব্যবহার করে বা সেট তৈরির সময় সরবরাহকারী কোনও তুলনাকারীর দ্বারা আদেশ করা হয় যা নির্মাতা ব্যবহার করা হচ্ছে তার উপর নির্ভর করে"

নোট করুন যে যোগ করুন, সরান এবং এর একটি সময় ব্যয় লগ আছে (এন)।

আপনি যদি অ্যারের হিসাবে সেটটির সামগ্রীটি অ্যাক্সেস করতে চান তবে আপনি এটি করে রূপান্তর করতে পারেন:

YourType[] array = someSet.toArray(new YourType[yourSet.size()]); 

এই অ্যারেটি ট্রিসেটের মতো একই মানদণ্ড অনুসারে বাছাই করা হবে (প্রাকৃতিক বা তুলনাকারী) এবং অনেক ক্ষেত্রে এটি অ্যারে করার পরিবর্তে একটি সুবিধা পাবে ort


4
আমি প্রথম উপাদান করা ArrayList Ei মত ক্রম প্রয়োজন cএবং তারপর উপাদান a:, আমি বারবার একটি সংগ্রহ উপর আমি তাদের একই আদেশ পেতে চান c, aইত্যাদি
Uko

4

TreeSet আদেশ করা হয়।

http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html


এটা সঠিক উত্তর. এলএইচসিটের বিপরীতে, ট্রিসেট java.util.SortSet প্রয়োগ করে
vemv

41
ক্রমযুক্ত এবং সাজানো বিভিন্ন জিনিস। ট্রিসেটটি বাছাই করা হয়েছে, অর্ডার করা হয়নি
Andrii

4
হুবহু, অর্ডার করা সন্নিবেশ অর্ডারকে বোঝায় (যেভাবে তালিকা তৈরি করে) কাজ করে, যখন সাজানো হয় কিছু মানদণ্ডের ভিত্তিতে উপাদানগুলির সত্য-পরবর্তী ক্রমকে বোঝায়।
কর্নেল ম্যাসন

1

ট্রিসেট হ'ল অর্ডারযুক্ত সেট, তবে আপনি কোনও আইটেম সূচকের মাধ্যমে অ্যাক্সেস করতে পারবেন না, কেবল পুনরাবৃত্তি করুন বা শুরু / শেষ দিকে যেতে পারেন।


ট্রিসেটের সাহায্যে আপনার বর্ধিত ব্যয় হবে। লিংকডহ্যাশসেটের দাম কম।
কার্লোস

0

যদি আমরা স্কিপ-লিস্টের সস্তা ব্যয়ের বাস্তবায়ন সম্পর্কে কথা বলি, আমি বিগ ও এর শর্তে অবাক হই, এই অপারেশনটির ব্যয়টি কী:

আপনার টাইপ [] অ্যারে = someSet.toArray (নতুন আপনার টাইপ [আপনারসেট.সাইজ ()]);

আমি বলতে চাইছি এটি সর্বদা পুরো অ্যারে সৃষ্টিতে আটকে থাকে তাই এটি ও (এন):

java.util.Arrays#copyOf

4
এটি পুনরুক্তির কার্যকারিতা বৈশিষ্ট্য এবং size()অন্তর্নিহিত সেটটির পদ্ধতির উপর নির্ভর করে । আইট্রেটেশন সাধারণত হয় O(n), আকারটি যেখানে থাকে তা O(1)বাদ দিয়ে সাধারণত হয় । ConcurrentSkipListSetO(n)
ইয়ান রবার্টস


0

গুগল পেয়ারাBiMap থেকে প্রাপ্ত বিডিরেশনাল মানচিত্রের থেকে আপনি কিছু উপযোগিতাও পেতে পারেন

একটি দিয়ে BiMap, আপনি খুব দক্ষতার সাথে অন্য কোনও অবজেক্টের ধরণের (র্যান্ডম সূচক অ্যাক্সেসের জন্য) পূর্ণসংখ্যার মানচিত্র তৈরি করতে পারেন। BiMapগুলি ওয়ান-টু-ওয়ান, সুতরাং যে কোনও প্রদত্ত পূর্ণসংখ্যার সাথে এটির সাথে সর্বাধিক একটি উপাদান যুক্ত থাকে এবং যে কোনও উপাদানটির একটিতে পূর্ণসংখ্যা থাকে। এটি চতুরতার সাথে দুটি HashTableদৃষ্টান্তের সাহায্যে তৈরি করা হয়েছে, সুতরাং এটি প্রায় দ্বিগুণ স্মৃতি ব্যবহার করে, তবে এটি Listপ্রক্রিয়াজাতকরণের তুলনায় অনেক বেশি কার্যকর কারণ contains()(যা কোনও আইটেম ইতিমধ্যে উপস্থিত রয়েছে কিনা তা পরীক্ষা করার জন্য যুক্ত করা হয়) একটি ধ্রুবক সময় এবং সমান্তরাল বান্ধব অপারেশনগুলির মতো HashSet, যখন Listএর বাস্তবায়ন অনেক ধীর।


0

আমারও একই সমস্যা ছিল। আমার বেশিরভাগ অর্ডার করা সেট নয় তবে দ্রুত indexOf/ সঙ্গে আরও একটি তালিকার দরকার ছিল contains। আমি সেখানে কিছুই খুঁজে না পেয়ে আমি নিজেই একটি প্রয়োগ করেছিলাম। কোডটি এখানে, এটি উভয়ই প্রয়োগ করে Setএবং Listযদিও সমস্ত বাল্ক তালিকার ক্রিয়াকলাপগুলি ArrayListসংস্করণগুলির চেয়ে তত দ্রুত নয় ।

অস্বীকৃতি: পরীক্ষিত নয়

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.Collection;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import static java.util.Objects.requireNonNull;

/**
 * An ArrayList that keeps an index of its content so that contains()/indexOf() are fast. Duplicate entries are
 * ignored as most other java Set's do.
 */
public class IndexedArraySet<E> extends ArrayList<E> implements Set<E> {

    public IndexedArraySet() { super(); }

    public IndexedArraySet(Iterable<E> c) {
        super();
        addAll(c);
    }

    private HashMap<E, Integer> indexMap = new HashMap<>();

    private void reindex() {
        indexMap.clear();
        int idx = 0;
        for (E item: this) {
            addToIndex(item, idx++);
        }
    }

    private E addToIndex(E e, int idx) {
        indexMap.putIfAbsent(requireNonNull(e), idx);
        return e;
    }

    @Override
    public boolean add(E e) {
        if(indexMap.putIfAbsent(requireNonNull(e), size()) != null) return false;
        super.add(e);
        return true;
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return addAll((Iterable<? extends E>) c);
    }
    public boolean addAll(Iterable<? extends E> c) {
        boolean rv = false;
        for (E item: c) {
            rv |= add(item);
        }
        return rv;
    }

    @Override
    public boolean contains(Object e) {
        return indexMap.containsKey(e);
    }

    @Override

    public int indexOf(Object e) {
        if (e == null) return -1;
        Integer i = indexMap.get(e);
        return (i == null) ? -1 : i;
    }

    @Override
    public int lastIndexOf(Object e) {
        return indexOf(e);
    }

    @Override @SuppressWarnings("unchecked")
    public Object clone() {
        IndexedArraySet clone = (IndexedArraySet) super.clone();
        clone.indexMap = (HashMap) indexMap.clone();
        return clone;
    }

    @Override
    public void add(int idx, E e) {
        if(indexMap.putIfAbsent(requireNonNull(e), -1) != null) return;
        super.add(idx, e);
        reindex();
    }

    @Override
    public boolean remove(Object e) {
        boolean rv;
        try { rv = super.remove(e); }
        finally { reindex(); }
        return rv;
    }

    @Override
    public void clear() {
        super.clear();
        indexMap.clear();
    }

    @Override
    public boolean addAll(int idx, Collection<? extends E> c) {
        boolean rv;
        try {
            for(E item : c) {
                // check uniqueness
                addToIndex(item, -1);
            }
            rv = super.addAll(idx, c);
        } finally {
            reindex();
        }
        return rv;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        boolean rv;
        try { rv = super.removeAll(c); }
        finally { reindex(); }
        return rv;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        boolean rv;
        try { rv = super.retainAll(c); }
        finally { reindex(); }
        return rv;
    }

    @Override
    public boolean removeIf(Predicate<? super E> filter) {
        boolean rv;
        try { rv = super.removeIf(filter); }
        finally { reindex(); }
        return rv;
    }

    @Override
    public void replaceAll(final UnaryOperator<E> operator) {
        indexMap.clear();
        try {
            int duplicates = 0;
            for (int i = 0; i < size(); i++) {
                E newval = requireNonNull(operator.apply(this.get(i)));
                if(indexMap.putIfAbsent(newval, i-duplicates) == null) {
                    super.set(i-duplicates, newval);
                } else {
                    duplicates++;
                }
            }
            removeRange(size()-duplicates, size());
        } catch (Exception ex) {
            // If there's an exception the indexMap will be inconsistent
            reindex();
            throw ex;
        }

    }

    @Override
    public void sort(Comparator<? super E> c) {
        try { super.sort(c); }
        finally { reindex(); }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.