プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

DartのHashSetの要素を順番に処理する

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

目次

  1. はじめに
  2. DartのHashSetの要素を順番に処理する
  3. forEachメソッドの基本的な使い方
  4. 要素を使って処理を行う
  5. forEachメソッド内での注意点
  6. おわりに

1. はじめに

こんにちは、iOS のエディタアプリPWEditorとその後継PWEditorNextの開発者の二俣です。
2018年5月から毎日技術ブログを更新しています。

今回はDartHashSetに格納されたすべての要素に対して、同じ処理を実行できるforEachメソッドについてです。

目次へ

2. DartのHashSetの要素を順番に処理する

DartHashSetでは、forEachメソッドを使用すると、格納されている要素を1つずつ取り出して処理できます。

forEachメソッドの形式は以下になります。

void forEach(void action(E element))

引数には、HashSetの各要素を受け取って処理する関数を指定します。

戻り値はありません。指定した関数が、HashSetに格納されている各要素に対して1回ずつ実行されます。

例えば、次のようなHashSetがあるとします。

import 'dart:collection';

void main() {
  final numbers = HashSet<int>();
  numbers.addAll([10, 20, 30]);

  numbers.forEach((number) {
    print(number);
  });
}

実行すると、HashSetの各要素が表示されます。

10
20
30

ただし、HashSetは要素の順序を保証しないため、表示順序は実行環境などによって異なる場合があります。

目次へ

3. forEachメソッドの基本的な使い方

forEachメソッドには、各要素を受け取る関数を指定します。処理が1行の場合は、アロー構文を使用して簡潔に記述できます。

import 'dart:collection';

void main() {
  final languages = HashSet<String>();
  languages.addAll(['Dart', 'Swift', 'C#']);

  languages.forEach((language) => print(language));
}

複数の処理を実行する場合は、ブロック形式で記述します。

languages.forEach((language) {
  print('言語: $language');
  print('文字数: ${language.length}');
});

forEachメソッドを呼び出しても、HashSetの要素が変更されることはありません。要素を追加、削除するためのメソッドではなく、各要素に対して処理を実行するためのメソッドです。

目次へ

4. 要素を使って処理を行う

forEachメソッドは、HashSetの各要素を表示したり、外部の変数へ値を追加したりする場合に利用できます。

import 'dart:collection';

void main() {
  final numbers = HashSet<int>();
  numbers.addAll([1, 2, 3, 4, 5]);

  var total = 0;

  numbers.forEach((number) {
    total += number;
  });

  print(total);
}

実行結果は以下になります。

15

ただし、要素を集計するだけであれば、foldreduceなどのメソッドを使用した方が、処理の意図が分かりやすくなる場合があります。

また、条件に一致する要素だけを取得したい場合は、wherefirstWhereなど、目的に合ったメソッドを利用します。

目次へ

5. forEachメソッド内での注意点

要素の順序は保証されない

HashSetは要素の順序を保証しません。そのため、forEachメソッドで処理する順序も保証されません。

処理順序が重要な場合は、ListLinkedHashSetなど、順序を管理できるコレクションを使用します。

処理中にHashSetを変更しない

forEachメソッドで要素を処理している途中に、対象のHashSetへ要素を追加したり削除したりすると、Concurrent modificationの例外が発生する可能性があります。

numbers.forEach((number) {
  // numbers.add(10);    // 処理中の追加は避ける
  // numbers.remove(1);  // 処理中の削除も避ける
  print(number);
});

要素を変更しながら処理したい場合は、あらかじめtoListなどでコピーを作成し、そのコピーを列挙する方法があります。

for (final number in numbers.toList()) {
  numbers.remove(number);
}

非同期処理には注意する

forEachasync関数を指定しても、各処理の完了を待つことはできません。非同期処理を順番に実行して完了を待ちたい場合は、for-in文とawaitを組み合わせます。

Future<void> main() async {
  final numbers = HashSet<int>();
  numbers.addAll([1, 2, 3]);

  for (final number in numbers) {
    await Future.delayed(const Duration(milliseconds: 100));
    print(number);
  }
}

リファレンス

Dart

DartPad

HashSet

Set

Iterable

Iterable.forEach

Iterable.toList

List

目次へ

6. おわりに

DartHashSetに格納されたすべての要素へ同じ処理を実行するには、forEachメソッドを使用します。

numbers.forEach((number) {
  print(number);
});

forEachメソッドは各要素を受け取る関数を指定して、HashSetの要素を1つずつ処理します。戻り値はなく、元のHashSetも変更しません。

ただし、HashSetは要素の順序を保証しないため、処理順序が重要な場合は注意が必要です。また、処理中にHashSetを変更することは避けてください。

HashSetの要素を表示したり、各要素に対して同じ処理を実行したりする場合に、forEachメソッドを利用できます。

目次へ


私が技術者として所属している ニューラル では、 組み込み・制御系ソフトウェアを中心に、モバイルアプリや業務アプリなど、さまざまなソフトウェアの開発を行っています。

組み込み分野では、リアルタイム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

目次へ