web-dev-qa-db-ja.com

セットに挿入する前に重複をチェックする必要がありますか

セットの使い方を学んでいます。私の質問は次のとおりです。セットには重複が含まれていません。重複を挿入しようとすると、エラーは発生せず、重複が自動的に削除されます。存在するかどうかに関係なく、セットに挿入する前に各値をチェックすることは良い習慣ですか?または、以下のコードのようなことをしても大丈夫ですか? Javaは内部で.contains(value)を使用してチェックを行うと思います。どう思いますか?

セットに入るn要素があると考えると、どちらの場合もBig Oの複雑さはどうなりますか?

import Java.util.HashSet;
import Java.util.Set;

public class DuplicateTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         Set<Integer> mySet = new HashSet<Integer>();

         mySet.add(10);
         mySet.add(20);
         mySet.add(30);
         mySet.add(40);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);
         mySet.add(50);

         System.out.println("Contents of the Hash Set :"+mySet);
    }

}
25
Zack

docs に従って:

public boolean add(E e)

指定された要素がまだ存在しない場合は、このセットに追加します。より正式には、このセットに要素e2が含まれていない場合、指定された要素eをこのセットに追加します(e == null?e2 == null:e.equals(e2))。 このセットにすでに要素が含まれている場合、呼び出しはセットを変更せずにfalseを返します。

そのため、add()メソッドはすでにtrueまたはfalseを返します。したがって、追加のチェックを行う必要はありません。

27
Atri

Set.add(E) のAPIドキュメントと比較してください

addメソッドは、要素がすでにSetにあるかどうかを確認します。要素がすでに存在する場合、新しい要素は追加されず、Setは変更されません。ほとんどの場合、何もチェックする必要はありません。

メソッドの複雑さは、使用しているSetの具体的な実装によって異なります。

10
Alejandro Goñi

チェックしないでください。これは、重複を自動的に除外するため、リストのセットに対する主な利点です。

HashSetのパフォーマンスは一定です( http://docs.Oracle.com/javase/8/docs/api/Java/util/HashSet.html

このクラスは、ハッシュ関数がバケット間で要素を適切に分散すると仮定して、基本的な操作(追加、削除、包含、サイズ)に一定の時間パフォーマンスを提供します

4
DMozzy

Add関数はブール値を返します。ブール値をチェックして、項目がすでにセットにあるかどうかを確認できます。これはもちろんあなたのニーズに基づいており、ベストプラクティスではありません。データベースからサロゲートキーに基づいて等値を定義している場合、既存の値を新しい情報で更新するために依存することはできないため、それが削除されることはありません。これは、マップが既存の値を返し、それを新しい値で置き換えるため、マップの動作とは逆です。

2
Greg L.

ここにあなたの質問への回答があります:

重複を挿入しようとすると、エラーは発生せず、重複が自動的に削除されます。

あなたの理解は正しくありません。 Set.add()を呼び出しても、既にセットに含まれている場合、新しいアイテムは追加されません。このステートメントは、SetHashSetを含む、TreeSetのすべての実装に適用されます。

存在するかどうかに関係なく、セットに挿入する前に各値をチェックすることは良い習慣ですか?または以下のコードのようなことをしても大丈夫ですか? Javaは.contains(value)を使用して内部的にチェックを行うと思います。どう思いますか?

最初から理解が間違っていたため、セットに挿入する前に各値をチェックして、すでに存在しているかどうかを確認する必要はありません。はい、内部的にはcontains()のようなことをしています。

セットに "n"個の要素が入ると考えると、どちらの場合もBig Ohの複雑さはどうなるでしょうか。

HashSetの場合、時間の複雑さはO(1)ごとにadd()です。使用しないTreeSet()の場合、時間の複雑さはO(lg N)ごとにadd()です。