さまざまなモジュールのデータを含むCSVファイルのセットを単純にループするメソッドを実装しました。これにより、「moduleName」がhashSetに追加されます。 (以下に示すコード)
HashSetを使用しました。これは、ArrayListの代わりに重複が挿入されないことを保証するためです。
ハッシュセットを使用すると、配列リストよりもパフォーマンスが向上すると思います。私はそれを述べることで正しいですか?
また、誰かが私に説明できます:
Big-O表記を使用した複雑さは何ですか?
HashSet<String> modulesUploaded = new HashSet<String>();
for (File f: marksheetFiles){
try {
csvFileReader = new CSVFileReader(f);
csvReader = csvFileReader.readFile();
csvReader.readHeaders();
while(csvReader.readRecord()){
String moduleName = csvReader.get("Module");
if (!moduleName.isEmpty()){
modulesUploaded.add(moduleName);
}
}
} catch (IOException e) {
e.printStackTrace();
}
csvReader.close();
}
return modulesUploaded;
}
私の実験 は、HashSet
がArrayList
よりも高速であることを示しています。
完全な結果表
| Boost | Collection Size |
| 2x | 3 elements |
| 3x | 10 elements |
| 6x | 50 elements |
| 12x | 200 elements | <= proportion 532-12 vs 10.000-200 elements
| 532x | 10.000 elements | <= shows linear lookup growth for the ArrayList
これらは完全に異なるクラスなので、質問は次のとおりです。どのような動作が必要ですか?
HashSet
は、重複がないことを確認し、O(1) contains()
メソッドを提供しますが、順序は保持しません。ArrayList
は重複がないことを保証しません。contains()
はO(n)ですが、エントリの順序を制御できます。
ハッシュセットを使用すると、配列リストよりもパフォーマンスが向上すると思います。私はそれを述べることで正しいですか?
多くの(意味が何であれ)エントリがあります。ただし、データサイズが小さい場合、生の線形検索はハッシュよりも高速になる可能性があります。損益分岐点がどこにあるのかを正確に測定する必要があります。私の直感では、要素が10個未満の場合、線形ルックアップはおそらく高速になります。 100を超える要素を使用したハッシュはおそらく高速ですが、それは単なる私の気持ちです...
HashSetからのルックアップは、要素のhashCode実装が正しければ、一定時間O(1)です。リストからの線形ルックアップは線形時間O(n)です。
データ構造の使用法に依存します。
データをHashSet
に格納していますが、ストレージの場合、HashSet
はArrayList
よりも優れています(重複エントリが必要ないため)。しかし、単に保管することは通常の意図ではありません。
保存されたデータをどのように読み取り、処理するかによって異なります。シーケンシャルアクセスまたはランダムインデックスベースのアクセスが必要な場合は、ArrayList
の方が適しています。または、順序が重要でない場合は、HashSet
の方が優れています。
順序が重要で、多くの変更(追加と削除)を行いたい場合は、LinkedListの方が適しています。
特定の要素にアクセスする場合、HashSet
はO(1)のような時間の複雑さを持ち、ArrayList
を使用した場合、あなた自身が指摘したようにO(N)になります。リストをiterate
して、要素が存在しないかどうかを確認します。