程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Qt學習之路(37): Qt容器類之關聯存儲容器

Qt學習之路(37): Qt容器類之關聯存儲容器

編輯:關於C語言

今天我們來說說Qt容器類中的關聯存儲容器。所謂關聯存儲容器,就是容器中存儲的一般是二元組,而不是單個的對象。二元組一般表述為<Key-Value>,也就是“鍵-值對”。   首先,我們看看數組的概念。數組可以看成是一種<int-Object>形式的鍵-值對,它的Key只能是int,而值的類型是Object,也就是任意類型(注意,這裡我們只是說數組可以是任意類型,這個Object並不必須是一個對象)。現在我們擴展數組的概念,把Key也做成任意類型的,而不僅僅是int,這樣就是一個關聯容器了。如果學過數據結構,典型的關聯容器就是散列(Hash Map,哈希表)。Qt提供兩種關聯容器類型:QMap<K, T>和QHash<K, T>。   QMap<K, T>是一種鍵-值對的數據結構,它實際上使用跳表skip-list實現,按照K進行升序的方式進行存儲。使用QMap<K, T>的insert()函數可以向QMap<K, T>中插入數據,典型的代碼如下:   QMap<QString, int> map;
map.insert("eins", 1);
map.insert("sieben", 7);
map.insert("dreiundzwanzig", 23);   同樣,QMap<K, T>也重載了[]運算符,你可以按照數組的復制方式進行使用:   map["eins"] = 1;
map["sieben"] = 7;
map["dreiundzwanzig"] = 23;   []操作符同樣也可以像數組一樣取值。但是請注意,如果在一個非const的map中,使用[]操作符取一個不存在的Key的值,則這個Key會被自動創建,並將其關聯的value賦予一個空值。如果要避免這種情況,請使用QMap<K, T>的value()函數:   int val = map.value("dreiundzwanzig");   如果key不存在,基本類型和指針會返回0,對象類型則會調用默認構造函數,返回一個對象,與[]操作符不同的是,value()函數不會創建一個新的鍵-值對。如果你希望讓不存在的鍵返回一個默認值,可以傳給value()函數第二個參數:   int seconds = map.value("delay", 30);   這行代碼等價於:   int seconds = 30;
if (map.contains("delay"))
        seconds = map.value("delay");   QMap<K, T>中的K和T可以是基本數據類型,如int,double,可以是指針,或者是擁有默認構造函數、拷貝構造函數和賦值運算符的類。並且K必須要重載<運算符,因為QMap<K, T>需要按K升序進行排序。   QMap<K, T>提供了keys()和values()函數,可以獲得鍵的集合和值的集合。這兩個集合都是使用QList作為返回值的。   Map是單值類型的,也就是說,如果一個新的值分配給一個已存在的鍵,則舊值會被覆蓋。如果你需要讓一個key可以索引多個值,可以使用QMultiMap<K, T>。這個類允許一個key索引多個value,如:   QMultiMap<int, QString> multiMap;
multiMap.insert(1, "one");
multiMap.insert(1, "eins");
multiMap.insert(1, "uno");

QList<QString> vals = multiMap.values(1);   QHash<K, T>是使用散列存儲的鍵-值對。它的接口同QMap<K, T>幾乎一樣,但是它們兩個的實現需求不同。QHash<K, T>的查找速度比QMap<K, T>快很多,並且它的存儲是不排序的。對於QHash<K, T>而言,K的類型必須重載了==操作符,並且必須被全局函數qHash()所支持,這個函數用於返回key的散列值。Qt已經為int、指針、QChar、QString和QByteArray實現了qHash()函數。   QHash<K, T>會自動地為散列分配一個初始大小,並且在插入數據或者刪除數據的時候改變散列的大小。我們可以使用reserve()函數擴大散列,使用squeeze()函數將散列縮小到最小大小(這個最小大小實際上是能夠存儲這些數據的最小空間)。在使用時,我們可以使用reserve()函數將數據項擴大到我們所期望的最大值,然後插入數據,完成之後使用squeeze()函數收縮空間。   QHash<K, T>同樣也是單值類型的,但是你可以使用insertMulti()函數,或者是使用QMultiHash<K, T>類來為一個鍵插入多個值。另外,除了QHash<K, T>,Qt也提供了QCache<K, T>來提供緩存,QSet<K>用於僅存儲key的情況。這兩個類同QHash<K, T>一樣具有K的類型限制。   遍歷關聯存儲容器的最簡單的辦法是使用Java風格的遍歷器。因為Java風格的遍歷器的next()和previous()函數可以返回一個鍵-值對,而不僅僅是值,例如:   QMap<QString, int> map;
...
int sum = 0;
QMapIterator<QString, int> i(map);
while (i.hasNext())
        sum += i.next().value();   如果我們並不需要訪問鍵-值對,可以直接忽略next()和previous()函數的返回值,而是調用key()和value()函數即可,如:   QMapIterator<QString, int> i(map);
while (i.hasNext()) {
        i.next();
        if (i.value() > largestValue) {
                largestKey = i.key();
                largestValue = i.value();
        }
}   Mutable遍歷器則可以修改key對應的值:   QMutableMapIterator<QString, int> i(map);
while (i.hasNext()) {
        i.next();
        if (i.value() < 0.0)
                i.setValue(-i.value());
}   如果是STL風格的遍歷器,則可以使用它的key()和value()函數。而對於foreach循環,我們就需要分別對key和value進行循環了:   QMultiMap<QString, int> map;
...
foreach (QString key, map.keys()) {
        foreach (int value, map.values(key)) {
                doSomething(key, value);
        }
}

本文出自 “豆子空間” 博客,請務必保留此出處http://devbean.blog.51cto.com/448512/248373

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved