誰かが、HashSet は追加、削除、包含、およびサイズに関して一定時間のパフォーマンスを提供すると言いました。
JavaDocs の実際のステートメントは、「このクラスは、ハッシュ関数が要素をバケット間で適切に分散すると仮定すると、基本的な操作 (追加、削除、含む、およびサイズ) に対して一定時間のパフォーマンスを提供します。」
これは、hashCode メソッドの実装が不十分な場合、セットに何かを追加するときに追加時間が遅くなる可能性があることを意味します。
次のコードは、hashCode の実装に応じて何が起こるかを示しています。
public void testHashSetAddition() {
for(int mod=10; mod <= 100; mod=mod+10 ) {
Set s = new HashSet();
long start = new Date().getTime();
for(int i=0; i<100000; i++) {
s.add(new Foo(i % mod));
}
long end = new Date().getTime();
System.out.println("Mod: " + mod + " - " + (end - start) + "ms");
}
}
class Foo {
private int hc;
public Foo(int i) {
this.hc = i;
}
public int hashCode() {
return hc;
}
}
タイミングの結果は次のとおりです。
Mod: 10 - 22683ms
Mod: 20 - 14200ms
Mod: 30 - 10486ms
Mod: 40 - 8562ms
Mod: 50 - 7761ms
Mod: 60 - 6740ms
Mod: 70 - 5778ms
Mod: 80 - 5268ms
Mod: 90 - 4716ms
Mod: 100 - 3966ms
次に、ArrayList に対してまったく同じテストを行います。
public void testAddingToArrayList() {
for(int mod=100; mod >= 10; mod=mod-10 ) {
List l = new ArrayList();
long start = new Date().getTime();
for(int i=0; i<100000; i++) {
l.add(new Foo(i % mod));
}
long end = new Date().getTime();
System.out.println("Mod: " + mod + " - " + (end - start) + "ms");
}
}
与えます:
Mod: 100 - 50ms
Mod: 90 - 30ms
Mod: 80 - 40ms
Mod: 70 - 30ms
Mod: 60 - 30ms
Mod: 50 - 40ms
Mod: 40 - 20ms
Mod: 30 - 30ms
Mod: 20 - 30ms
Mod: 10 - 30ms