سؤال

وأنا أعلم عن SortedSet, لكن في حالتي أحتاج إلى شيء يمكن تنفيذه List, ، و لا Set.فهل يوجد تطبيق هناك، في واجهة برمجة التطبيقات (API) أو في أي مكان آخر؟

لا ينبغي أن يكون من الصعب تنفيذ الأمر بنفسي، لكنني فكرت لماذا لا أسأل الناس هنا أولاً؟

هل كانت مفيدة؟

المحلول

وليس هناك جمع جافا في المكتبة القياسية للقيام بذلك. LinkedHashSet<E> يحافظ على طلب مماثل لList، على الرغم من ، حتى إذا كنت التفاف مجموعة الخاصة بك في List عندما تريد استخدامه بمثابة List ستحصل على دلالات تريد.

وبدلا من ذلك، العموم مجموعات (أو commons-collections4، لإصدار عام) لديها وList الذي يفعل ما تريد بالفعل: <لأ href = "https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.2/index.html؟org/apache/commons/collections/ قائمة / SetUniqueList.html "يختلط =" noreferrer "> SetUniqueList / <لأ href =" https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/list /SetUniqueList.html "يختلط =" noreferrer "> SetUniqueList<E> .

نصائح أخرى

وهنا هو ما فعلته، وأنه يعمل.

وعلى افتراض لدي ArrayList للعمل مع أول شيء فعلته تم إنشاء LinkedHashMap جديدة.

LinkedHashSet<E> hashSet = new LinkedHashSet<E>()

وبعد ذلك أحاول أن أضم عنصرا جديدا إلى LinkedHashSet. طريقة إضافة لا يغير LinkedHasSet وإرجاع كاذبة إذا كان العنصر الجديد هو نسخة مكررة. حتى يصبح هذا شرط يمكنني اختبار قبل إضافة إلى ArrayList.

if (hashSet.add(E)) arrayList.add(E);

وهذا هو وسيلة بسيطة وأنيقة لمنع مكررة من إضافتها إلى قائمة مجموعة. إذا أردت يمكنك تغليف في وتجاوز أسلوب الوظيفة فئة التي تمتد ArrayList. فقط تذكر للتعامل مع addAll بواسطة حلقات من خلال العناصر واستدعاء الأسلوب إضافة.

وحتى هنا ما فعلته في نهاية المطاف. آمل أن يساعد هذا شخص آخر.

class NoDuplicatesList<E> extends LinkedList<E> {
    @Override
    public boolean add(E e) {
        if (this.contains(e)) {
            return false;
        }
        else {
            return super.add(e);
        }
    }

    @Override
    public boolean addAll(Collection<? extends E> collection) {
        Collection<E> copy = new LinkedList<E>(collection);
        copy.removeAll(this);
        return super.addAll(copy);
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> collection) {
        Collection<E> copy = new LinkedList<E>(collection);
        copy.removeAll(this);
        return super.addAll(index, copy);
    }

    @Override
    public void add(int index, E element) {
        if (this.contains(element)) {
            return;
        }
        else {
            super.add(index, element);
        }
    }
}   

يجب أن تفكر بجدية في إجابة ديلر:

  1. بدلاً من القلق بشأن إضافة كائناتك إلى قائمة خالية من التكرارات، قم بإضافتها إلى مجموعة (أي تطبيق)، والتي ستقوم بطبيعتها بتصفية التكرارات.
  2. عندما تحتاج إلى استدعاء الطريقة التي تتطلب قائمة، قم بتغليفها في ملف new ArrayList(set) (أو أ new LinkedList(set), ، أيا كان).

أعتقد أن الحل الذي نشرته مع NoDuplicatesList لديه بعض المشاكل، معظمها مع contains() الطريقة، بالإضافة إلى أن فصلك لا يتعامل مع التحقق من التكرارات في المجموعة التي تم تمريرها إلى ملفك addAll() طريقة.

لماذا لا تغلف مجموعة مع القائمة، نوع مثل:

new ArrayList( new LinkedHashSet() )

وهذا يترك تنفيذ الآخرين للشخص الذي هو سيد الحقيقي للمجموعات، -)

وأنا في حاجة إلى شيء من هذا القبيل، لذلك ذهبت إلى المجموعات المشتركة، واستخدمت SetUniqueList، ولكن عندما ركضت بعض اختبار الأداء، وجدت أنه لا يبدو الأمثل مقارنة مع حالة إذا كنت ترغب في استخدام مجموعة والحصول على مجموعة باستخدام طريقة Set.toArray ()، اتخذ SetUniqueTest 20: 1 الوقت لملء ثم اجتياز 100000 سلاسل مقارنة لimplementaion الآخر الذي هو الفرق صفقة كبيرة، لذلك إذا كنت تقلق بشأن الأداء، فإنني أوصي لكم لاستخدام مجموعة والحصول على صفيف بدلا من استخدام SetUniqueList، إلا إذا كنت حقا بحاجة الى منطق SetUniqueList، ثم تحتاج إلى التحقق من حلول أخرى ...

والأسلوب الرئيسي كود الاختبار:

والجمهور ساكنة باطلة الرئيسي (سلسلة [] وسائط) {

SetUniqueList pq = SetUniqueList.decorate(new ArrayList());
Set s = new TreeSet();

long t1 = 0L;
long t2 = 0L;
String t;


t1 = System.nanoTime();
for (int i = 0; i < 200000; i++) {
    pq.add("a" + Math.random());
}
while (!pq.isEmpty()) {
    t = (String) pq.remove(0);
}
t1 = System.nanoTime() - t1;

t2 = System.nanoTime();
for (int i = 0; i < 200000; i++) {
    s.add("a" + Math.random());
}

s.clear();
String[] d = (String[]) s.toArray(new String[0]);
s.clear();
for (int i = 0; i < d.length; i++) {
    t = d[i];

}
t2 = System.nanoTime() - t2;

System.out.println((double)t1/1000/1000/1000); //seconds
System.out.println((double)t2/1000/1000/1000); //seconds
System.out.println(((double) t1) / t2);        //comparing results

و}

والتحيات محمد سليم http://abusleem.net/blog

ملحوظة:لا يستغرق قائمة فرعية التنفيذ بعين الاعتبار.

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class UniqueList<T> extends ArrayList<T> {

    private static final long serialVersionUID = 1L;

    /** Unique elements SET */
    private final Set<T> set=new HashSet();

    /** Used by addAll methods */
    private Collection<T> addUnique(Collection<? extends T> col) {
        Collection<T> unique=new ArrayList();
        for(T e: col){
            if (set.add(e)) unique.add(e);
        }
        return unique;
    }

    @Override
    public boolean add(T e) {
        return set.add(e) ? super.add(e) : false;
    }

    @Override
    public boolean addAll(Collection<? extends T> col) {
        return super.addAll(addUnique(col));
    }

    @Override
    public void add(int index, T e) {
        if (set.add(e)) super.add(index, e);
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> col) {
        return super.addAll(index, addUnique(col));
    }

}

ثائق واجهات جمع يقول:

<اقتباس فقرة>   

ومجموعة - مجموعة التي لا تحتوي على عناصر مكررة
.   قائمة - مجموعة أمر (تسمى أحيانا تسلسل). قوائم يمكن أن تحتوي على عناصر مكررة.

وحتى إذا كنت لا تريد التكرارات، وربما كنت لا ينبغي استخدام القائمة.

وفي طريقة add، لماذا لا تستخدم HashSet.add() للتحقق مكررة بدلا من HashSet.consist(). سوف HashSet.add() عودة true إذا لم مكررة وfalse خلاف ذلك.

ومن على قمة رأسي، والقوائم تسمح التكرارات. هل يمكن تنفيذ بسرعة UniqueArrayList وتجاوز جميع وظائف add / insert للتحقق من contains() قبل استدعاء الأساليب الموروثة. للاستخدام الشخصي، هل يمكن أن تنفذ فقط طريقة add التي تستخدمها، وتجاوز الآخرين بطرح استثناء في حالة المبرمجين في المستقبل في محاولة لاستخدام قائمة بطريقة مختلفة.

ولقد قدمت بلدي UniqueList في مكتبتي الخاصة قليلا مثل هذا:

package com.bprog.collections;//my own little set of useful utilities and classes

import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Jonathan
*/
public class UniqueList {

private HashSet masterSet = new HashSet();
private ArrayList growableUniques;
private Object[] returnable;

public UniqueList() {
    growableUniques = new ArrayList();
}

public UniqueList(int size) {
    growableUniques = new ArrayList(size);
}

public void add(Object thing) {
    if (!masterSet.contains(thing)) {
        masterSet.add(thing);
        growableUniques.add(thing);
    }
}

/**
 * Casts to an ArrayList of unique values
 * @return 
 */
public List getList(){
    return growableUniques;
}

public Object get(int index) {
    return growableUniques.get(index);
}

public Object[] toObjectArray() {
    int size = growableUniques.size();
    returnable = new Object[size];
    for (int i = 0; i < size; i++) {
        returnable[i] = growableUniques.get(i);
    }
    return returnable;
    }
}

ولدي فئة TestCollections التي تبدو مثل هذا:

package com.bprog.collections;
import com.bprog.out.Out;
/**
*
* @author Jonathan
*/
public class TestCollections {
    public static void main(String[] args){
        UniqueList ul = new UniqueList();
        ul.add("Test");
        ul.add("Test");
        ul.add("Not a copy");
        ul.add("Test"); 
        //should only contain two things
        Object[] content = ul.toObjectArray();
        Out.pl("Array Content",content);
    }
}

ويعمل بشكل جيد. كل ما يفعله هو أنه يضيف إلى مجموعة إذا لم يكن لديك بالفعل وليس هناك أي Arraylist الذي يمكن إرجاعه، فضلا عن مجموعة وجوه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top