92

私はについて知ってSortedSetいますが、私の場合は、ではなく、を実装するものが必要ListですSet。それで、APIまたは他の場所に実装がありますか?

自分で実装するのは難しいことではありませんが、最初にここの人に聞いてみませんか?

4

12 に答える 12

98

これを行うためのJavaコレクションは標準ライブラリにありません。LinkedHashSet<E>ただし、と同様に順序を保持するため、セットをとして使用するときにListセットをaでラップすると、必要なセマンティクスが得られます。ListList

あるいは、Commons Collections(またはcommons-collections4、汎用バージョンの場合)には、Listすでに必要なことを実行するがあります:SetUniqueList/ SetUniqueList<E>

于 2008-11-06T13:38:42.440 に答える
15

これが私がやったことで、うまくいきます。

で作業する必要があると仮定するArrayListと、最初に行ったのは新しいLinkedHashMap.

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

次に、新しい要素をに追加しようとしLinkedHashSetます。add メソッドは を変更せずLinkedHasSet、新しい要素が重複している場合は false を返します。したがって、これは、に追加する前にテストできる条件になりArrayListます。

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

これは、重複が配列リストに追加されるのを防ぐ簡単で洗練された方法です。必要に応じて、それをカプセル化し、 を拡張するクラスで add メソッドをオーバーライドできますArrayListaddAll要素をループして add メソッドを呼び出すことを忘れないでください。

于 2014-04-24T17:36:24.533 に答える
11

それで、これが私が最終的にしたことです。これが他の誰かに役立つことを願っています。

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);
        }
    }
}   
于 2008-11-06T14:15:51.553 に答える
6

セットをリストでカプセル化して、次のように並べ替えてみませんか。

new ArrayList( new LinkedHashSet() )

これは、コレクションの本当のマスターである誰かのために他の実装を残します;-)

于 2008-11-06T13:32:55.743 に答える
4

ディラーの答えを真剣に検討する必要があります。

  1. オブジェクトを重複のないリストに追加することを心配する代わりに、オブジェクトをセット(任意の実装)に追加します。これにより、本来、重複が除外されます。
  2. リストを必要とするメソッドを呼び出す必要がある場合は、それをnew ArrayList(set)(または、new LinkedList(set)など)でラップします。

で投稿したソリューションにはNoDuplicatesList、主にメソッドにいくつかの問題があると思いcontains()ます。さらに、クラスは、メソッドに渡されたコレクション内の重複のチェックを処理しませんaddAll()

于 2008-11-06T16:28:24.360 に答える
3

そういうものが必要だったので、コモンズコレクションに行ってを使ったのですが、性能テストを行ったところ、を使ってメソッドを使ってを取得しSetUniqueListたい場合に比べて最適化されていないように見えました。SetArraySet.toArray()

他の実装と比較SetUniqueTestして、 20:1 の時間で100,000 文字列を埋めてトラバースし、これは大きな違いです。

したがって、パフォーマンスが心配な場合は、 のロジックが本当に必要でない限り、の代わりにSet and Get an Arrayを使用することをお勧めします。その後、他の解決策を確認する必要があります...SetUniqueListSetUniqueList

コードのメインメソッドのテスト:

public static void main(String[] args) {


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

}

よろしく、 モハメッド・スリーム

于 2009-07-21T20:50:41.167 に答える
1

注: subListの実装は考慮されていません。

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));
    }

}
于 2016-03-04T05:32:04.060 に答える
0

コレクションインターフェイスのドキュメントには次のように書かれています。

セット—重複する要素を含めることができないコレクション。
リスト—順序付けられたコレクション(シーケンスと呼ばれることもあります)。リストには重複する要素を含めることができます。

したがって、重複が必要ない場合は、リストを使用しないでください。

于 2008-11-06T13:35:48.343 に答える
0

私の頭のてっぺんから、リストは重複を許可します。継承されたメソッドを呼び出す前に、 aをすばやく実装し、すべての/関数をUniqueArrayListオーバーライドしてチェックすることができます。個人的な使用の場合は、使用するメソッドのみを実装し、他のメソッドをオーバーライドして、将来のプログラマーが別の方法でリストを使用しようとした場合に備えて例外をスローすることができます。addinsertcontains()add

于 2008-11-06T13:40:51.640 に答える
-1

メソッドでは、代わりに重複をチェックするためにadd使用しないのはなぜですか。 重複がない場合は返され、そうでない場合は返されます。HashSet.add()HashSet.consist()HashSet.add()truefalse

于 2012-01-13T13:07:43.753 に答える
-3

次のように、独自の小さなライブラリに独自の 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 とオブジェクト配列がある場合は、セットに追加するだけです。

于 2011-10-06T19:22:16.710 に答える