私はの実装見つけようとしているjava.util.List
とjava.util.Set
、Javaで同時にします。このクラスで一意の要素(as Set
)のみを許可し、それらの順序(like List
)を保持する必要があります。JDK 6に存在しますか?
List<T>#add(int, T)
特定の位置に挿入できるようにすることが重要です。
回答:
TreeSet
要素の順序でソートされます。LinkedHashSet
挿入順序を保持します。うまくいけば、それらの1つはあなたが求めていたものです。
任意の場所に挿入できるように指定しましたが、独自に作成する必要があると思います。aHashSet<T>
とArrayList<T>
;を含むクラスを作成するだけです。アイテムを追加するときは、リストに追加する前に、セットに含まれているかどうかを確認してください。
あるいは、Apacheのcommons-collections4オファーListOrderedSet
とSetUniqueList
、は同様に動作し、指定された要件を満たす必要があります。
LinkedHashSetがその答えです。
反復順序と一意性。
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
List
インターフェイスは実装されていません。質問に対する私の変更を参照してください
のような意味LinkedHashSet
ですか?これにより、エントリの順序は保持されますが、重複は許可されません。
IMHO、それは珍しい要件ですが、重複することなくリストを書くことができます。
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
インターフェイスは実装されていません。質問に対する私の変更を参照してください
O(n)
挿入の複雑さがないため見栄えが良く、二重ストレージとO(log(n))
挿入操作の間で考慮しなければならないトレードオフがあります。
あなたは実装できないList
とSet
契約違反せずに一度に。たとえば、Set.hashCode
契約を参照してください。
セットのハッシュコードは、セット内の要素のハッシュコードの合計として定義されます。ここで、null要素のハッシュコードはゼロとして定義されます。
一方、ここにの契約がありList.hashCode
ます:
リストのハッシュコードは、次の計算の結果として定義されます。
int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
したがって、両方の契約が履行されることを保証する単一のクラスを実装することは不可能です。equals
実装についても同じ問題。
JDK 6に限定しない場合は、必要に応じて完全に一致するApache CommonCollectionsライブラリ(ListOrderedSet)を使用できます。それは似ていてList
、Set
一緒に組み合わされています:)
List
インターフェース
もう1つのオプション(List
インターフェイス要件を除く)はImmutableSet
、挿入順序を保持するGuavaです。彼らのウィキページから:
ソートされたコレクションを除いて、順序は構築時から保持されます。例えば、
ImmutableSet.of("a", "b", "c", "a", "d", "b")
「a」、「b」、「c」、「d」の順序で要素を繰り返し処理します。
Comparator
?で定義された順序を保持することを意味しますか?また、List
インターフェースのセマンティクスも必要ですか?