はじめに
この実験では、Java コレクション内の重複要素を効率的にチェックする方法を学びます。Java コレクションフレームワークの強力なツールである HashSet
を使って重複を特定する方法を探ります。
実践的な手順を通じて、まず HashSet
の要素の一意性を利用して重複を検出する方法を学びます。次に、元のコレクションとそれから作成した HashSet
のサイズを比較することで、別の方法を見つけます。最後に、重複をチェックする際に null 要素をどう扱うかを調べます。
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
この実験では、Java コレクション内の重複要素を効率的にチェックする方法を学びます。Java コレクションフレームワークの強力なツールである HashSet
を使って重複を特定する方法を探ります。
実践的な手順を通じて、まず HashSet
の要素の一意性を利用して重複を検出する方法を学びます。次に、元のコレクションとそれから作成した HashSet
のサイズを比較することで、別の方法を見つけます。最後に、重複をチェックする際に null 要素をどう扱うかを調べます。
このステップでは、Java の HashSet
を使ってコレクション内の重複要素を効率的にチェックする方法を探ります。HashSet
は Java コレクションフレームワークの一部で、一意の要素を格納し、非常に高速な検索が可能なため特に便利です。
まず、~/project
ディレクトリに DuplicateCheck.java
という名前の新しい Java ファイルを作成しましょう。WebIDE のファイルエクスプローラーで、ファイルリストエリアを右クリックして「New File」を選択し、DuplicateCheck.java
と入力することで作成できます。
次に、コードエディターで DuplicateCheck.java
ファイルを開き、以下のコードを追加します。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DuplicateCheck {
public static void main(String[] args) {
// Create a list with some duplicate elements
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Alice"); // Duplicate
names.add("Charlie");
names.add("Bob"); // Duplicate
System.out.println("Original List: " + names);
// Use a HashSet to find duplicates
Set<String> uniqueNames = new HashSet<>();
Set<String> duplicates = new HashSet<>();
for (String name : names) {
if (!uniqueNames.add(name)) {
// If add returns false, the element is already in the set
duplicates.add(name);
}
}
System.out.println("Duplicates found: " + duplicates);
}
}
このコードの新しい部分を分解してみましょう。
import java.util.ArrayList;
, import java.util.HashSet;
, import java.util.List;
, import java.util.Set;
: これらの行は、リストとセットを操作するために Java ユーティリティライブラリから必要なクラスをインポートします。List<String> names = new ArrayList<>();
: これは String
オブジェクトを保持できる List
である names
を作成します。List
インターフェースの具体的な実装として ArrayList
を使用しています。names.add(...)
: これは names
リストに要素を追加します。「Alice」と「Bob」が 2 回追加されていることに注意してください。Set<String> uniqueNames = new HashSet<>();
: これは HashSet
実装を使用して uniqueNames
という Set
を作成します。Set
は一意の要素のみを含むことを保証します。Set<String> duplicates = new HashSet<>();
: これは見つかった重複要素を格納するための別の Set
を作成します。for (String name : names)
: これは names
リスト内の各 name
を反復処理する for-each
ループです。if (!uniqueNames.add(name))
: HashSet
の add()
メソッドは、要素が正常に追加された場合(つまり、セット内にまだ存在しなかった場合)は true
を返し、要素がすでに存在する場合は false
を返します。!
は結果を反転させるため、if
ブロック内のコードは add()
が false
を返すとき、つまり重複があるときにのみ実行されます。duplicates.add(name);
: 重複が見つかった場合、それを duplicates
セットに追加します。DuplicateCheck.java
ファイルを保存します(Ctrl+S または Cmd+S)。
次に、WebIDE の下部にあるターミナルを開きます。~/project
ディレクトリにいることを確認してください。pwd
と入力して Enter キーを押すことで確認できます。出力は /home/labex/project
であるはずです。
javac
コマンドを使用して Java プログラムをコンパイルします。
javac DuplicateCheck.java
エラーがなければ、何も出力されないはずです。これはコンパイルが成功し、~/project
ディレクトリに DuplicateCheck.class
ファイルが作成されたことを意味します。ls
コマンドを実行することで確認できます。
最後に、java
コマンドを使用してコンパイルされた Java プログラムを実行します。
java DuplicateCheck
以下のような出力が表示されるはずです。
Original List: [Alice, Bob, Alice, Charlie, Bob]
Duplicates found: [Alice, Bob]
HashSet
は挿入順序を保持しないため、「Duplicates found」の出力における要素の順序は異なる場合があります。
あなたは HashSet
を使ってリスト内の重複要素を正常に特定することができました!
前のステップでは、HashSet
を使って重複要素を見つけました。Set
の重要な特性は、一意の要素のみを格納することです。つまり、Set
に重複要素を追加すると、各要素のインスタンスは 1 つだけ保持されます。この特性は、リストから重複を削除するなどのタスクに非常に便利です。
このステップでは、元のリスト(重複要素を含む可能性があります)のサイズと、そのリストから作成された HashSet
(一意の要素のみを含みます)のサイズを比較することで、この特性を示すように DuplicateCheck.java
プログラムを修正します。
WebIDE のコードエディターで DuplicateCheck.java
ファイルを開きます。
main
メソッドを以下のように修正します。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DuplicateCheck {
public static void main(String[] args) {
// Create a list with some duplicate elements
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Alice"); // Duplicate
names.add("Charlie");
names.add("Bob"); // Duplicate
names.add("David");
System.out.println("Original List: " + names);
System.out.println("Size of Original List: " + names.size());
// Create a HashSet from the list
Set<String> uniqueNamesSet = new HashSet<>(names);
System.out.println("Set created from List: " + uniqueNamesSet);
System.out.println("Size of Set: " + uniqueNamesSet.size());
// The difference in size tells us how many duplicates were removed
int duplicatesCount = names.size() - uniqueNamesSet.size();
System.out.println("Number of duplicates (excluding first occurrence): " + duplicatesCount);
}
}
追加または変更した部分は次のとおりです。
names
リストに別の名前「David」を追加して、少し大きなリストにしました。System.out.println("Size of Original List: " + names.size());
: size()
メソッドを使って元のリストのサイズを出力します。Set<String> uniqueNamesSet = new HashSet<>(names);
: これは別の Collection
(ここでは ArrayList
)から直接 HashSet
を作成する便利な方法です。このようにすると、HashSet
は自動的にリストのすべての要素を追加し、Set
であるため、重複要素は破棄されます。System.out.println("Size of Set: " + uniqueNamesSet.size());
: HashSet
のサイズを出力します。このサイズは一意の要素の数を表します。int duplicatesCount = names.size() - uniqueNamesSet.size();
: リストのサイズとセットのサイズの差を計算します。この差は、(最初の出現を除いた)重複要素の数を示します。修正した DuplicateCheck.java
ファイルを保存します。
次に、ターミナルでプログラムを再度コンパイルします。
javac DuplicateCheck.java
コンパイルが成功したら、プログラムを実行します。
java DuplicateCheck
以下のような出力が表示されるはずです。
Original List: [Alice, Bob, Alice, Charlie, Bob, David]
Size of Original List: 6
Set created from List: [Alice, Bob, Charlie, David]
Size of Set: 4
Number of duplicates (excluding first occurrence): 2
元のリストのサイズは 6 ですが、それから作成された HashSet
のサイズは 4 であることに注意してください。差(6 - 4 = 2)は、2 つの重複名(「Alice」と「Bob」が最初の出現後にそれぞれ 1 回ずつ登場した)があったことを正しく示しています。
これは、HashSet
を使ってコレクション内の一意の要素の数や重複要素の数を簡単に見つけることができることを示しています。
前のステップでは、HashSet
が非ヌルの重複要素をどのように扱うかを見てきました。今度は、null
要素を追加しようとしたときの HashSet
の動作を調べてみましょう。コレクションが null
をどのように扱うかを理解することは重要です。なぜなら、注意深く扱わないと、予期しない動作やエラーにつながることがあるからです。
HashSet
は 1 つの null
要素を許可します。null
を複数回追加しようとすると、最初の null
のみが格納されます。
これをテストするために、DuplicateCheck.java
プログラムをもう一度修正しましょう。
WebIDE のコードエディターで DuplicateCheck.java
ファイルを開きます。
main
メソッドを修正して、リストに null
値を含めます。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DuplicateCheck {
public static void main(String[] args) {
// Create a list with some duplicate and null elements
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add(null); // Add null
names.add("Alice"); // Duplicate
names.add("Charlie");
names.add(null); // Add null again
names.add("Bob"); // Duplicate
names.add("David");
names.add(null); // Add null a third time
System.out.println("Original List: " + names);
System.out.println("Size of Original List: " + names.size());
// Create a HashSet from the list
Set<String> uniqueNamesSet = new HashSet<>(names);
System.out.println("Set created from List: " + uniqueNamesSet);
System.out.println("Size of Set: " + uniqueNamesSet.size());
// The difference in size tells us how many duplicates were removed
// Note: This calculation is less straightforward with nulls and duplicates combined
// int duplicatesCount = names.size() - uniqueNamesSet.size();
// System.out.println("Number of duplicates (excluding first occurrence): " + duplicatesCount);
}
}
ここでは、names
リストに複数回 null
を追加しています。また、null
が含まれる場合、重複数の計算があまり意味を持たなくなるため、重複数の計算部分をコメントアウトしています。今回は null
を含めたセットの動作に焦点を当てています。
修正した DuplicateCheck.java
ファイルを保存します。
ターミナルでプログラムをコンパイルします。
javac DuplicateCheck.java
コンパイルが成功したら、プログラムを実行します。
java DuplicateCheck
以下のような出力が表示されるはずです。
Original List: [Alice, Bob, null, Alice, Charlie, null, Bob, David, null]
Size of Original List: 9
Set created from List: [null, Alice, Bob, Charlie, David]
Size of Set: 5
出力を見てみましょう。
Original List
には、複数の null
値を含むすべての要素が表示されています。そのサイズは 9 です。Set created from List
には一意の要素のみが含まれています。リストに複数回 null
が追加されていても、セット内では null
が 1 回だけ表示されていることに注意してください。セットのサイズは 5(Alice、Bob、Charlie、David、および null)です。これにより、HashSet
が 1 つの null
要素を許可し、それ以降の null
の追加を他の要素と同じように重複として扱うことが確認できます。
これで、HashSet
が null
要素をどのように扱うかを正常にテストできました。これで、HashSet
を使った重複チェックと、一意の要素および null
要素に対する動作の調査は終了です。
この実験では、Java のコレクション内の重複要素を HashSet
を使って効率的にチェックする方法を学びました。重複要素を含む List
を作成し、それを反復処理して、各要素を HashSet
に追加しようとしました。add()
メソッドの戻り値をチェックすることで、要素がすでに存在する場合は false
を返すため、重複要素を識別して別の HashSet
に収集することができました。この方法は、HashSet
の一意の要素特性と高速な検索機能を利用して、効果的な重複検出を行います。