この記事は 2026 年 8 月 19 日に投稿しました。

目次
- はじめに
- DartのHashSetから指定した位置の要素を取得する
- elementAtメソッドのインデックス
- 範囲外のインデックスを指定した場合
- elementAtメソッドを使用する場合の注意点
- おわりに
1. はじめに
こんにちは、iOS のエディタアプリPWEditorとその後継PWEditorNextの開発者の二俣です。
2018年5月から毎日技術ブログを更新しています。
今回はDartのHashSetから、指定したインデックスの要素を取得するelementAtメソッドについてです。
2. DartのHashSetから指定した位置の要素を取得する
DartのHashSetでは、elementAtメソッドを使用すると、反復順序における指定したインデックスの要素を取得できます。
elementAtメソッドの形式は以下になります。
E elementAt(int index)
引数indexに、取得したい要素のインデックスを指定します。
インデックスは0から始まります。
例えば、次のHashSetがあるとします。
final languages = HashSet<String>(); languages.addAll([ 'Dart', 'Flutter', 'Swift', ]);
elementAtメソッドを使用すると、次のように要素を取得できます。
final language = languages.elementAt(0);
print(language);
この場合、HashSetの反復順序で最初に位置する要素が取得されます。
実装例
import 'dart:collection'; void main() { final languages = HashSet<String>(); languages.addAll([ 'Dart', 'Flutter', 'Swift', ]); final language = languages.elementAt(0); print(language); }
ここで注意したいのが、HashSetでは要素の順序が保証されていないという点です。
例えば、
languages.elementAt(0)
としたからといって、最初に追加したDartが必ず取得できるわけではありません。
HashSetは順序を管理するためのコレクションではなく、要素の反復順序は規定されていません。
そのため、elementAtメソッドは、
追加した順番の0番目の要素を取得する
という意味ではなく、
現在の反復順序における0番目の要素を取得する
と考える必要があります。
複数の要素をインデックスを指定して取得することもできます。
import 'dart:collection'; void main() { final numbers = HashSet<int>(); numbers.addAll([ 10, 20, 30, 40, ]); for (var i = 0; i < numbers.length; i++) { print(numbers.elementAt(i)); } }
この例では、0からlength - 1までのインデックスを指定して、すべての要素を取得しています。
ただし、表示される順番が、
10 20 30 40
になるとは限りません。
単純にすべての要素を順番に処理したいだけであれば、elementAtメソッドではなくfor-inを使用する方が分かりやすい場合があります。
for (final number in numbers) { print(number); }
elementAtメソッドは、反復可能なコレクションから特定の位置にある要素だけを取得したい場合などに利用できます。
3. elementAtメソッドのインデックス
elementAtメソッドで指定するインデックスは0から始まります。
例えば、3つの要素がある場合に指定できるインデックスは、
0 1 2
です。
elementAt(0)は反復順序の最初の要素を取得します。
final value = set.elementAt(0);
これはfirstプロパティを使用する場合と同じ位置の要素になります。
final value1 = set.elementAt(0); final value2 = set.first;
どちらも、そのSetの反復順序における最初の要素を取得します。
例えば、次のように使用できます。
import 'dart:collection'; void main() { final set = HashSet<String>(); set.addAll([ 'Dart', 'Flutter', 'Swift', ]); print(set.elementAt(0)); print(set.first); }
また、最後の要素をelementAtメソッドで取得する場合は、
final value = set.elementAt(set.length - 1);
と指定できます。
ただし、最後の要素を取得することが目的であれば、lastプロパティを使用した方が意図が分かりやすくなります。
final value = set.last;
例えば、
import 'dart:collection'; void main() { final set = HashSet<int>(); set.addAll([ 10, 20, 30, ]); print(set.elementAt(set.length - 1)); print(set.last); }
とできます。
ただし、ここでいう「最初」や「最後」もHashSetの反復順序における最初と最後です。
追加した順番の最初や最後という意味ではありません。
また、elementAtメソッドはIterableで定義されているメソッドです。
そのため、HashSetだけでなく、Listやその他のIterableでも利用できます。
例えばListの場合は、
final languages = [ 'Dart', 'Flutter', 'Swift', ]; print(languages.elementAt(1));
とすると、
Flutter
が取得できます。
Listはインデックス順に要素が並んでいるため、この場合のelementAt(1)は明確に2番目の要素を表します。
一方、HashSetでは順序が保証されないため、同じelementAtメソッドでも、この違いを意識して使用する必要があります。
4. 範囲外のインデックスを指定した場合
elementAtメソッドに指定できるインデックスは、
0 <= index && index < length
の範囲です。
例えば、要素数が3の場合は、
0 1 2
を指定できます。
3以上を指定することはできません。
例えば、次のコードでは要素が3つしかないにもかかわらず、elementAt(3)を実行しています。
import 'dart:collection'; void main() { final set = HashSet<String>(); set.addAll([ 'Dart', 'Flutter', 'Swift', ]); print(set.elementAt(3)); }
この場合、インデックスが要素の範囲外となるためエラーになります。
また、負の値を指定することもできません。
print(set.elementAt(-1));
そのため、変数でインデックスを指定する場合は、事前に範囲を確認しておくと安全です。
例えば、次のようにできます。
import 'dart:collection'; void main() { final set = HashSet<String>(); set.addAll([ 'Dart', 'Flutter', 'Swift', ]); const index = 1; if (index >= 0 && index < set.length) { print(set.elementAt(index)); } }
要素が空の場合も、指定できる有効なインデックスはありません。
final set = HashSet<String>(); print(set.elementAt(0));
この場合も要素を取得することはできません。
空かどうかを確認してから最初の要素を取得するのであれば、例えば、
if (set.isNotEmpty) {
print(set.elementAt(0));
}
とできます。
ただし、単に最初の要素を取得したい場合には、
if (set.isNotEmpty) {
print(set.first);
}
とした方が意図が分かりやすいでしょう。
このようにelementAtメソッドを使用する場合は、指定するインデックスが0以上かつlength未満であることに注意する必要があります。
5. elementAtメソッドを使用する場合の注意点
HashSetでelementAtメソッドを使用する場合、最も重要なのは要素の順序が保証されていない点です。
例えば、
import 'dart:collection'; void main() { final languages = HashSet<String>(); languages.add('Dart'); languages.add('Flutter'); languages.add('Swift'); print(languages.elementAt(0)); print(languages.elementAt(1)); print(languages.elementAt(2)); }
とした場合でも、
Dart Flutter Swift
という追加順で取得できることは保証されていません。
そのため、
final firstLanguage = languages.elementAt(0);
として、
最初に追加した言語
という意味で使用するべきではありません。
追加した順番を維持したい場合は、LinkedHashSetを利用する方法があります。
LinkedHashSetでは、要素は挿入順に反復されます。
例えば、
import 'dart:collection'; void main() { final languages = LinkedHashSet<String>(); languages.add('Dart'); languages.add('Flutter'); languages.add('Swift'); print(languages.elementAt(0)); print(languages.elementAt(1)); print(languages.elementAt(2)); }
の場合は、挿入順に、
Dart Flutter Swift
と取得できます。
一方、インデックスを利用した要素へのアクセスを頻繁に行うのであれば、SetではなくListを利用する方が適している場合もあります。
例えば、
final languages = [ 'Dart', 'Flutter', 'Swift', ]; print(languages[1]);
とすると、Flutterを取得できます。
Listはインデックスを使用して要素を扱うコレクションなので、
languages[1]
のような記述ができます。
一方、HashSetには、
set[1]
のようなインデックス演算子による要素取得はありません。
elementAtメソッドは、HashSetにインデックスが付与されているという意味ではなく、反復順序をたどって指定位置の要素を取得するためのメソッドです。
DartのelementAtメソッドは、必要に応じて反復順序で要素をたどり、指定した位置までの要素を読み飛ばして対象の要素を返すことがあります。
そのため、
set.elementAt(index)
を繰り返し使用してすべての要素を処理するよりも、
for (final value in set) { // 処理 }
のように直接反復した方が処理の意図も分かりやすくなります。
また、順序を決めてから特定位置の要素を取得したい場合は、Listへ変換して並べ替える方法もあります。
例えば、
import 'dart:collection'; void main() { final numbers = HashSet<int>(); numbers.addAll([ 30, 10, 40, 20, ]); final sortedNumbers = numbers.toList()..sort(); print(sortedNumbers.elementAt(0)); print(sortedNumbers.elementAt(1)); }
sortを実行した後は、
10 20 30 40
という順番になるため、
sortedNumbers.elementAt(0)
では10、
sortedNumbers.elementAt(1)
では20を取得できます。
このように、
順序は必要ないが重複を持たせたくない
場合はHashSet、
挿入順を維持したSetを使用したい
場合はLinkedHashSet、
インデックスによって要素を扱いたい
場合はList
というように、用途に合わせてコレクションを使い分けることも重要です。
なお、elementAtメソッド自体はHashSet固有のメソッドではありません。
Iterableで定義されているメソッドなので、HashSet以外のさまざまな反復可能オブジェクトで使用できます。
リファレンス
6. おわりに
DartのHashSetから、反復順序における指定した位置の要素を取得するには、elementAtメソッドを使用します。
例えば、
final set = HashSet<String>(); set.addAll([ 'Dart', 'Flutter', 'Swift', ]); final value = set.elementAt(0);
とすると、HashSetの反復順序で0番目にある要素を取得できます。
インデックスは0から始まるため、要素数が3の場合に指定できるインデックスは、
0 1 2
になります。
指定するインデックスは、
0 <= index && index < set.length
の範囲である必要があります。
ただし、HashSetでelementAtメソッドを使用する際に特に注意したいのが、要素の順序が保証されていないことです。
そのため、
set.elementAt(0)
で取得される要素を、
最初に追加した要素
と考えることはできません。
挿入順を維持したい場合はLinkedHashSet、インデックスによる要素の操作を中心に行いたい場合はListを使用することも検討するとよいでしょう。
また、単純にすべての要素を処理する場合は、
for (final value in set) { // 処理 }
のようにfor-inを使用する方が分かりやすい場合があります。
elementAtメソッドは、反復可能なコレクションの中から特定の位置にある要素だけを取得したい場合に利用できるメソッドです。
私が技術者として所属している ニューラル では、 組み込み・制御系ソフトウェアを中心に、モバイルアプリや業務アプリなど、さまざまなソフトウェアの開発を行っています。
組み込み分野では、リアルタイムOSを利用したシステム開発をはじめ、弊社製品のハイブリッドOS Bi-OS など、長年培ってきた組み込み・制御系の技術を活かした開発に取り組んでいます。
また、iOS(Swift/SwiftUI)やWindows(C#)をはじめとしたアプリケーション開発、Webシステムの開発などにも対応しています。
組み込みソフトウェア、モバイルアプリ、Windowsアプリ、Webシステムなど、ソフトウェア開発に関するご相談がございましたら、お気軽にお問い合わせください。
また、ニューラルでは一緒にソフトウェア開発に取り組んでいただける技術者の方も募集しています。
ご興味がございましたら、お気軽にお問い合わせください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688