memo

プログラミング備忘録





【Qt】QMap備忘録

QMapは似たようなクラスをJavaで見かけた気がします。
Qtのmapは全然触っておらずわからなすぎるので、実践的に使う前に簡単にまとめておこうと思います。

公式よりQMapクラスの説明一部……

QMap is one of Qt's generic container classes. It stores (key, value) pairs and provides fast lookup of the value associated with a key.

https://doc.qt.io/qt-5/qmap.html#details
かなり省略すると、キーとキーに対応する値のペアを保持するクラスとのこと。



例1)
QMapクラスのmapは、キーをint型、キーに対する値にQString型で宣言しています。
最後にキーが25に対応する値をデバッグで表示します。

    QMap<int, QString> map;
    map[26] = "Raichu";
    map[25] = "Pikachu";
    map.insert(172, "Pichu");
    int num = map.count(); // ペアの個数
    qDebug("name=%s", qPrintable(map[25]));

出力結果

name=Pikachu

ここで少し気になったのが、デバッグ画面ではキーが小さい順にソートされていました。
挿入順等ではないのですね。

f:id:shinopikapi:20191124185036p:plain
例1デバッグ画面



例2)
QMapクラスのqmapは、キーをQString型、キーに対する値にint型で宣言しています。

    QMap<QString,int> qmap;
    qmap["aaaa"] = 1;
    qmap.insert("bbbb", 2);

マップの追加はどちらの方法でも出来るようです。
値を取得するときは、例1と同様にキーを指定します。


・個数を返す
int QMap::count() const
int QMap::size() const


・追加
配列のように括弧[ ]の中にキー、値を代入でも、insert()でも可能。

    QMap<QString,int> qmap;
    qmap[キーをここ] = キーに対応する値;
    qmap.insert(キー, 値);


・初期化
例1の後にこちらで初期化出来ているのが確認出来ました。
どちらでも可能。

    map = {};
    map.clear();


・取得
例1よりキーを指定して以下のようにします。

    QString name = map[26];

存在しないキーを指定した場合、例1ではQStringで空、例2ではintの値で0が返ってきました。
存在しないキーを指定してもエラーにならないっぽいですね。

……と思っていたのですが、以下のようにすると

    QString name = map[20];// 存在しないキー

name=""にはなりますが、今まで存在していなかったキー値で対応する値は空のマップが新たに追加されていました。

f:id:shinopikapi:20191124210516p:plain
例1のデバッグ画面 map追加
なので、何も考えなしに存在しないキーの値も含めて取得しようしたら、いつの間にかマップが大きくなっているところでした。


・空かどうか
マップ自体が空(初期化されている状態)かどうかは、個数確認count()やsize()でも出来ます。
bool QMap::empty() const
bool QMap::isEmpty() const

キーが存在するかどうかは以下で確認出来ます。
存在する場合はtrueを返します。
bool QMap::contains(const Key &key) const
例1より、存在しないキー値21で有無を確認してみると、testはfalseでした。

    bool test = map.contains(21);// 存在しないキー
    qDebug("exist=%d", test);

出力結果

exist=0


・キーが重複した場合
結論から申し上げると、重複した場合、後で設定した値に上書きされるようです。

Normally, a QMap allows only one value per key. If you call insert() with a key that already exists in the QMap, the previous value will be erased.
~略~
However, you can store multiple values per key by using insertMulti() instead of insert() (or using the convenience subclass QMultiMap). If you want to retrieve all the values for a single key, you can use values(const Key &key), which returns a QList:

そして、一つのキーに対して複数の値を設定したい場合はQMultiMapクラスを使用しよう、とのことでした。

    QMap<int, QString> map;
    map[25] = "Pikachu";
    qDebug("name=%s", qPrintable(map[25]));

    map.insert(25,"MegaPikachu");
    qDebug("name=%s", qPrintable(map[25]));

出力結果

name=Pikachu
name=MegaPikachu

重複したので後で設定した値が表示されました。

QMapもまだまだ関数はありますが、ひとまずこのくらいはすぐ使うと思ったのでメモ。


参考:
https://doc.qt.io/qt-5/qmap.html