關聯容器(QMap、QHash...)


關聯容器(Associative Container)為Key/Value匹配的容器,Qt提供的關鍵之一為QMap,可根據Key來快速取得相對應的Value。

您可以使用QMap的insert()方法指定Key/Value插入QMap中,使用QMap的value()指定Key來取得對應的Value,例如:
QMap<QString, QString> map;

map.insert("caterpillar", "caterpillar's message!");
map.insert("momor", "momor's message!");
   
cout << map.value("caterpillar").toAscii().data() << endl;
cout << map.value("momor").toAscii().data() << endl;

也可以直接使用[]及=來指定Key/Value,或是使用[]根據Key取得
Value,使用上就如同關聯陣列,例如:
QMap<QString, QString> map;

map["caterpillar"] = "caterpillar's message!";
map["momor"] = "momor's message!";
   
cout << map["caterpillar"].toAscii().data() << endl;
cout << map["caterpillar"].toAscii().data() << endl;

使用QMap的[]或value()方法指定Key來取得Value時,如果沒有該Key,則會根據Value類別的預設建構 子產生一個新物件並傳回,如果是基本資料型態則或指標則傳回0,不過value()有另一個版本,也可以指定當Key不存在時,傳回的預設值,例如:
QString message = map.value("bush", "N.A.");

假設map中原先並沒有儲存"bush"作為 Key的相對應Value,則上式將會傳回"N.A"的QString。QMap中的Key/Value可以放置基本資料型態、物件、指標,物件必須有預 設建構子、複製建構子與指定運算子,QMap中的排序是根據Key作遞增排序,所以Key的部份還必須提供<()運算子以判斷Key的排序先後。

如果想要迭代QMap中的Key/Value,可以使用keys()與values()方法,它們各傳回QList物件,當中各包括Key與Value:
QMap<QString, QString> map;

map["caterpillar"] = "caterpillar's message!";
map["momor"] = "momor's message!";
map["bush"] = "bush's message!";
   
QList<QString> keys = map.keys();   
foreach(QString key, keys) {
    cout << key.toAscii().data() << " " << endl;
}
cout << endl;
   
QList<QString> values = map.values();
foreach(QString value, values) {
    cout << value.toAscii().data() << " " << endl;
}
cout << endl;   

您也可以直接使用QMapIterator來進行迭代,直接來看個實例:
QMap<QString, QString> map;

map.insert("caterpillar", "caterpillar's message!");
map.insert("momor", "momor's message!");
map.insert("bush", "bush's message!");
   
QMapIterator<QString, QString> iterator(map);
while(iterator.hasNext()) {
    iterator.next();
    cout << iterator.key().toAscii().data() << endl;
    cout << iterator.value().toAscii().data() << endl;
}

QMapIterator是唯讀迭代器,如果在迭代過程中想要 修改,則可以使用QMutableIterator。一般來說,Map中的Key/Value是一對一,您如果在QMap中基於同一個Key插入了兩個不 同的Value,則後者會覆蓋前者,但QMultiMap讓您可以在一個Key上指定多個Value,它是QMap的子類別,可使用values()方法 傳回某Key所對應的數個Value,例如:
QMultiMap<QString, QString> map;

map.insert("caterpillar", "caterpillar's message1!");
map.insert("caterpillar", "momor's message2!");
   
QList<QString> values = map.values("caterpillar");

與QMap作用類似的是QHash,它是基於雜湊表(Hash table)的關聯容器,使用介面與QMap也幾乎相同,但QHash是無序的,其內部雜湊表會自動依需要自動增長,您可以使用reserve()來保留 雜湊表大小,或是squeeze() 來縮減雜湊表大小。

QHash
中的Key/Value可以放置基本資料型態、物件、指標,物件必須有預設建構子、複製建構子與 指定運算子(基本上,這是放至容器中的物件之基本需求),QHash的Key是基於雜湊表,所以Key還必須提供==運算子,以及全域的qHash()函 式,以計算出Key的雜湊值,Qt本身已提供許多基本的qHash()函式,可以協助您計算Key的雜湊值,可以參考Qt的QHash類別說明,當中有定 義的範例可以參考。

如果想要基於一個Key儲存多個Value,則可以使用QHash的子類別QMultiHash。

如果只想要儲存Key,則可以使用QSet。