Qt における Java 形式のイテレータ

Javaスタイルのイテレータ

各コンテナ・クラスには、2 つの Java スタイルのイテレータ・データ型があります。

注: 新しいコードでは、STLスタイルのイテレータを使用する必要があります。STLスタイルのイテレータの方が効率的で、QtやSTLのgeneric algorithms

コンテナ読み取り専用イテレータ読み書きイテレータ
QList<t>,QQueue<t>,QStack<t>、QListIterator<T>QMutableListIterator<T>
QSet<T>QSetIterator<T>QMutableSetIterator<T>
QMap<Key, T>,QMultiMap<Key, T>QMapIterator<キー、TQMutableMapIterator<キー、T
QHash<Key, T>,QMultiHash<Key, T>QHashIterator<キー、TQMutableHashIterator<キー、T

この議論では、QListQMap に集中する。QSet QList同様に、QHash のイテレータ型は、QMap のイテレータ型と同じインタフェースを持つ。

STLスタイルのイテレータとは異なり、Javaスタイルのイテレータは、アイテムを直接指すのではなく、アイテム間を指す。このため、イテレータはコンテナの先頭(最初のアイテムの前)、コンテナの最後(最後のアイテムの後)、または2つのアイテムの間を指します。下の図は、4つの項目を含むリストについて、有効なイテレータの位置を赤い矢印で示しています:

以下は、QList<QString> のすべての要素を順番に反復処理する典型的なループです:

QList<QString> list = {"A", "B", "C", "D"};

QListIterator<QString> i(list);
while (i.hasNext())
    QString s = i.next();

これは次のように動作する:繰り返し処理するQList は、QListIterator コンストラクタに渡される。その時点で、イテレータはリストの最初の項目のすぐ前(項目 "A "の前)に位置している。次に、hasNext ()を呼び出して、イテレータの後に項目があるかどうかをチェックする。ある場合は、next() を呼び出して、その項目を飛び越えます。next()関数は、飛び越えた項目を返す。QList<QString>の場合、その項目の型はQString です。

以下は、QList を逆方向に反復する方法である:

QListIterator<QString> i(list);
i.toBack();
while (i.hasPrevious())
    QString s = i.previous();

toBack() を呼び出してイテレータをリストの最後のアイテムの後に移動させることから始めることを除けば、コードは前方への反復処理と対称的である。

下図は、next ()とprevious ()をイテレーターに呼び出した場合の効果を示しています:

次の表に、QListIterator API の概要を示します:

関数動作
toFront()イテレーターをリストの先頭(最初のアイテムの前)に移動する。
toBack()イテレータをリストの後ろ(最後の項目の後)に移動する
hasNext()イテレータがリストの後ろにない場合はtrue を返します。
next()次の項目を返し、イテレータを 1 つ進めます。
peekNext()イテレータを移動させずに次の項目を返す
hasPrevious()イテレータがリストの先頭にない場合にtrue を返す
previous()前の項目を返し、イテレータを 1 つ後ろに移動させる
peekPrevious()イテレータを移動させずに前の項目を返す

QListIterator には、反復処理中にリストに項目を挿入したり削除したりする関数はありません。これを実現するには、 を使用する必要があります。 を使って、 <int>からすべての奇数を削除する例を示します:QMutableListIterator QMutableListIterator QList

QMutableListIterator<int> i(list);
while (i.hasNext()) {
    if (i.next() % 2 != 0)
        i.remove();
}

ループ内のnext()呼び出しは毎回行われる。これはリストの次の項目にジャンプします。remove() 関数は、リストからジャンプオーバーした最後の項目を削除する。remove() の呼び出しはイテレータを無効にしないので、イテレータを使い続けても安全です。これは、逆方向に反復するときにも同様に機能する:

QMutableListIterator<int> i(list);
i.toBack();
while (i.hasPrevious()) {
    if (i.previous() % 2 != 0)
        i.remove();
}

既存のアイテムの値を変更するだけなら、setValue ()を使用できます。以下のコードでは、128より大きい値をすべて128に置き換えている:

QMutableListIterator<int> i(list);
while (i.hasNext()) {
    if (i.next() > 128)
        i.setValue(128);
}

remove() と同様に、setValue() は、最後にジャンプした項目を操作する。前方に反復する場合、これはイテレータの直前の項目であり、後方に反復する場合、これはイテレータの直後の項目である。

next()関数は、リスト内の項目へのconstでない参照を返す。単純な操作では、setValue() は必要ありません:

QMutableListIterator<int> i(list);
while (i.hasNext())
    i.next() *= 2;

前述のように、QSet のイテレータ・クラスは、QList とまったく同じ API を持っています。ここでは、QMapIterator について説明します。 は、(key, value) のペアを反復処理するので、多少異なります。

QListIterator と同様、QMapIterator は、toFront()、toBack()、hasNext()、next()、peekNext()、hasPrevious()、previous()、peekPrevious() を提供する。キーと値のコンポーネントは、next()、peekNext()、previous()、または peekPrevious() によって返されたオブジェクトに対してkey() およびvalue() を呼び出して抽出します。

以下の例では、首都名が "City" で終わるすべての (capital, country) ペアを削除しています:

QMap<QString, QString> map = {
    {"Paris", "France"},
    {"Guatemala City", "Guatemala"},
    {"Mexico City", "Mexico"},
    {"Moscow", "Russia"}
};
...

QMutableMapIterator<QString, QString> i(map);
while (i.hasNext()) {
    if (i.next().key().endsWith("City"))
        i.remove();
}

QMapIterator また、 () および () 関数も用意されており、イテレータを直接操作して、イテレータが上にジャンプした最後の項目のキーと値を返します。例えば、以下のコードは の内容を にコピーしている:key value QMap QHash

QMap<int, QWidget *> map;
QHash<int, QWidget *> hash;

QMapIterator<int, QWidget *> i(map);
while (i.hasNext()) {
    i.next();
    hash.insert(i.key(), i.value());
}

同じ値を持つすべての項目を繰り返し処理したい場合は、findNext ()またはfindPrevious ()を使用します。以下は、特定の値を持つ項目をすべて削除する例です:

QMutableMapIterator<int, QWidget *> i(map);
while (i.findNext(widget))
    i.remove();

本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。