私はについて知ってSortedSet
いますが、私の場合は、ではなく、を実装するものが必要List
ですSet
。それで、APIまたは他の場所に実装がありますか?
自分で実装するのは難しいことではありませんが、最初にここの人に聞いてみませんか?
私はについて知ってSortedSet
いますが、私の場合は、ではなく、を実装するものが必要List
ですSet
。それで、APIまたは他の場所に実装がありますか?
自分で実装するのは難しいことではありませんが、最初にここの人に聞いてみませんか?
これを行うためのJavaコレクションは標準ライブラリにありません。LinkedHashSet<E>
ただし、と同様に順序を保持するため、セットをとして使用するときにList
セットをaでラップすると、必要なセマンティクスが得られます。List
List
あるいは、Commons Collections(またはcommons-collections4
、汎用バージョンの場合)には、List
すでに必要なことを実行するがあります:SetUniqueList
/ SetUniqueList<E>
。
これが私がやったことで、うまくいきます。
で作業する必要があると仮定するArrayList
と、最初に行ったのは新しいLinkedHashMap
.
LinkedHashSet<E> hashSet = new LinkedHashSet<E>()
次に、新しい要素をに追加しようとしLinkedHashSet
ます。add メソッドは を変更せずLinkedHasSet
、新しい要素が重複している場合は false を返します。したがって、これは、に追加する前にテストできる条件になりArrayList
ます。
if (hashSet.add(E)) arrayList.add(E);
これは、重複が配列リストに追加されるのを防ぐ簡単で洗練された方法です。必要に応じて、それをカプセル化し、 を拡張するクラスで add メソッドをオーバーライドできますArrayList
。addAll
要素をループして add メソッドを呼び出すことを忘れないでください。
それで、これが私が最終的にしたことです。これが他の誰かに役立つことを願っています。
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);
}
}
}
セットをリストでカプセル化して、次のように並べ替えてみませんか。
new ArrayList( new LinkedHashSet() )
これは、コレクションの本当のマスターである誰かのために他の実装を残します;-)
ディラーの答えを真剣に検討する必要があります。
new ArrayList(set)
(または、new LinkedList(set)
など)でラップします。で投稿したソリューションにはNoDuplicatesList
、主にメソッドにいくつかの問題があると思いcontains()
ます。さらに、クラスは、メソッドに渡されたコレクション内の重複のチェックを処理しませんaddAll()
。
そういうものが必要だったので、コモンズコレクションに行ってを使ったのですが、性能テストを行ったところ、を使ってメソッドを使ってを取得しSetUniqueList
たい場合に比べて最適化されていないように見えました。Set
Array
Set.toArray()
他の実装と比較SetUniqueTest
して、 20:1 の時間で100,000 文字列を埋めてトラバースし、これは大きな違いです。
したがって、パフォーマンスが心配な場合は、 のロジックが本当に必要でない限り、の代わりにSet and Get an Arrayを使用することをお勧めします。その後、他の解決策を確認する必要があります...SetUniqueList
SetUniqueList
コードのメインメソッドのテスト:
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
}
よろしく、 モハメッド・スリーム
注: 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));
}
}
コレクションインターフェイスのドキュメントには次のように書かれています。
セット—重複する要素を含めることができないコレクション。
リスト—順序付けられたコレクション(シーケンスと呼ばれることもあります)。リストには重複する要素を含めることができます。
したがって、重複が必要ない場合は、リストを使用しないでください。
私の頭のてっぺんから、リストは重複を許可します。継承されたメソッドを呼び出す前に、 aをすばやく実装し、すべての/関数をUniqueArrayList
オーバーライドしてチェックすることができます。個人的な使用の場合は、使用するメソッドのみを実装し、他のメソッドをオーバーライドして、将来のプログラマーが別の方法でリストを使用しようとした場合に備えて例外をスローすることができます。add
insert
contains()
add
メソッドでは、代わりに重複をチェックするためにadd
使用しないのはなぜですか。
重複がない場合は返され、そうでない場合は返されます。HashSet.add()
HashSet.consist()
HashSet.add()
true
false
次のように、独自の小さなライブラリに独自の 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 とオブジェクト配列がある場合は、セットに追加するだけです。