在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C/ Qt 容器類(lèi)之關(guān)聯(lián)存儲(chǔ)容器
Qt 容器和算法拾遺
自定義 model 之一
反走樣
Hello, world!
Qt 容器類(lèi)之關(guān)聯(lián)存儲(chǔ)容器
QStringListModel
拖放技術(shù)之一
狀態(tài)欄
QTreeWidget
拖放技術(shù)之二
通用算法
event()
Qt 學(xué)習(xí)之路(18): Qt 標(biāo)準(zhǔn)對(duì)話(huà)框之 QInputDialog
Qt 容器類(lèi)之遍歷器和隱式數(shù)據(jù)共享
QListWidget
Meta-Object 系統(tǒng)
事件接收與忽略
Qt 學(xué)習(xí)之路(tip): parent 參數(shù)
Qt 標(biāo)準(zhǔn)對(duì)話(huà)框之 QColorDialog
QPainter(續(xù))
國(guó)際化(下)
漸變填充
自定義委托
創(chuàng)建 shared library
model-view 架構(gòu)
Graphics View Framework
自定義拖放數(shù)據(jù)對(duì)象
QSortFilterProxyModel
國(guó)際化(上)
組件布局
自定義 Model 之三
事件過(guò)濾器
QDirModel
Hello, world!(續(xù))
Qt 標(biāo)準(zhǔn)對(duì)話(huà)框之 QFileDialog
自定義 model 之二
深入了解信號(hào)槽
坐標(biāo)變換
剪貼板操作
QTableWidget
QByteArray 和 QVariant
創(chuàng)建一個(gè)對(duì)話(huà)框(下)
Qt 學(xué)習(xí)之路(32): 一個(gè)簡(jiǎn)易畫(huà)板的實(shí)現(xiàn)(Graphics View)
文本文件讀寫(xiě)
自定義事件
編寫(xiě)跨平臺(tái)的程序
MainWindow
初探信號(hào)槽
Qt 學(xué)習(xí)之路(17): Qt 標(biāo)準(zhǔn)對(duì)話(huà)框之 QMessageBox
繪圖設(shè)備
菜單和工具條(續(xù))
二進(jìn)制文件讀寫(xiě)
QString
事件(event)
菜單和工具條
QPainter
Qt 容器類(lèi)之順序存儲(chǔ)容器
進(jìn)程間交互
API 文檔的使用
創(chuàng)建一個(gè)對(duì)話(huà)框(上)
一個(gè)簡(jiǎn)易畫(huà)板的實(shí)現(xiàn)(QWidget)

Qt 容器類(lèi)之關(guān)聯(lián)存儲(chǔ)容器

今天我們來(lái)說(shuō)說(shuō) Qt 容器類(lèi)中的關(guān)聯(lián)存儲(chǔ)容器。所謂關(guān)聯(lián)存儲(chǔ)容器,就是容器中存儲(chǔ)的一般是二元組,而不是單個(gè)的對(duì)象。二元組一般表述為,也就是“鍵-值對(duì)”。

首先,我們看看數(shù)組的概念。數(shù)組可以看成是一種形式的鍵-值對(duì),它的 Key 只能是int,而值的類(lèi)型是 Object,也就是任意類(lèi)型(注意,這里我們只是說(shuō)數(shù)組可以是任意類(lèi)型,這個(gè)Object 并不必須是一個(gè)對(duì)象)?,F(xiàn)在我們擴(kuò)展數(shù)組的概念,把 Key 也做成任意類(lèi)型的,而不僅僅是int,這樣就是一個(gè)關(guān)聯(lián)容器了。如果學(xué)過(guò)數(shù)據(jù)結(jié)構(gòu),典型的關(guān)聯(lián)容器就是散列(Hash Map,哈希表)。Qt 提供兩種關(guān)聯(lián)容器類(lèi)型:QMap<K, T>和 QHash<K, T>。

QMap<K, T>是一種鍵-值對(duì)的數(shù)據(jù)結(jié)構(gòu),它實(shí)際上使用跳表 skip-list 實(shí)現(xiàn),按照 K 進(jìn)行升序的方式進(jìn)行存儲(chǔ)。使用 QMap<K, T>的 insert()函數(shù)可以向 QMap<K, T>中插入數(shù)據(jù),典型的代碼如下:


QMap<QString, int> map; 
map.insert("eins", 1); 
map.insert("sieben", 7); 
map.insert("dreiundzwanzig", 23);

同樣,QMap<K, T>也重載了[]運(yùn)算符,你可以按照數(shù)組的復(fù)制方式進(jìn)行使用:


map["eins"] = 1; 
map["sieben"] = 7; 
map["dreiundzwanzig"] = 23;

[]操作符同樣也可以像數(shù)組一樣取值。但是請(qǐng)注意,如果在一個(gè)非 const 的 map 中,使用[]操作符取一個(gè)不存在的 Key 的值,則這個(gè) Key 會(huì)被自動(dòng)創(chuàng)建,并將其關(guān)聯(lián)的 value 賦予一個(gè)空值。如果要避免這種情況,請(qǐng)使用 QMap<K, T>的 value()函數(shù):


int val = map.value("dreiundzwanzig");

如果 key 不存在,基本類(lèi)型和指針會(huì)返回0,對(duì)象類(lèi)型則會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù),返回一個(gè)對(duì)象,與[]操作符不同的是,value()函數(shù)不會(huì)創(chuàng)建一個(gè)新的鍵-值對(duì)。如果你希望讓不存在的鍵返回一個(gè)默認(rèn)值,可以傳給 value()函數(shù)第二個(gè)參數(shù):


int seconds = map.value("delay", 30);

這行代碼等價(jià)于:


int seconds = 30; 
if (map.contains("delay")) 
        seconds = map.value("delay");

QMap<K, T>中的K和T可以是基本數(shù)據(jù)類(lèi)型,如 int,double,可以是指針,或者是擁有默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的類(lèi)。并且K必須要重載<運(yùn)算符,因?yàn)?QMap<K, T>需要按 K 升序進(jìn)行排序。

QMap<K, T>提供了 keys()和 values()函數(shù),可以獲得鍵的集合和值的集合。這兩個(gè)集合都是使用QList 作為返回值的。

Map 是單值類(lèi)型的,也就是說(shuō),如果一個(gè)新的值分配給一個(gè)已存在的鍵,則舊值會(huì)被覆蓋。如果你需要讓一個(gè) key 可以索引多個(gè)值,可以使用 QMultiMap<K, T>。這個(gè)類(lèi)允許一個(gè) key 索引多個(gè) 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>是使用散列存儲(chǔ)的鍵-值對(duì)。它的接口同 QMap<K, T>幾乎一樣,但是它們兩個(gè)的實(shí)現(xiàn)需求不同。QHash<K, T>的查找速度比 QMap<K, T>快很多,并且它的存儲(chǔ)是不排序的。對(duì)于 QHash<K, T>而言,K 的類(lèi)型必須重載了==操作符,并且必須被全局函數(shù) qHash()所支持,這個(gè)函數(shù)用于返回 key的散列值。Qt 已經(jīng)為 int、指針、QChar、QString 和 QByteArray 實(shí)現(xiàn)了 qHash()函數(shù)。

QHash<K, T>會(huì)自動(dòng)地為散列分配一個(gè)初始大小,并且在插入數(shù)據(jù)或者刪除數(shù)據(jù)的時(shí)候改變散列的大小。我們可以使用 reserve()函數(shù)擴(kuò)大散列,使用 squeeze()函數(shù)將散列縮小到最小大小(這個(gè)最小大小實(shí)際上是能夠存儲(chǔ)這些數(shù)據(jù)的最小空間)。在使用時(shí),我們可以使用 reserve()函數(shù)將數(shù)據(jù)項(xiàng)擴(kuò)大到我們所期望的最大值,然后插入數(shù)據(jù),完成之后使用 squeeze()函數(shù)收縮空間。

QHash<K, T>同樣也是單值類(lèi)型的,但是你可以使用 insertMulti()函數(shù),或者是使用QMultiHash<K, T>類(lèi)來(lái)為一個(gè)鍵插入多個(gè)值。另外,除了 QHash<K, T>,Qt 也提供了 QCache<K, T>來(lái)提供緩存,QSet用于僅存儲(chǔ) key 的情況。這兩個(gè)類(lèi)同 QHash<K, T>一樣具有 K 的類(lèi)型限制。

遍歷關(guān)聯(lián)存儲(chǔ)容器的最簡(jiǎn)單的辦法是使用 Java 風(fēng)格的遍歷器。因?yàn)?Java 風(fēng)格的遍歷器的 next()和previous()函數(shù)可以返回一個(gè)鍵-值對(duì),而不僅僅是值,例如:


QMap<QString, int> map; 
... 
int sum = 0; 
QMapIterator<QString, int> i(map); 
while (i.hasNext()) 
        sum += i.next().value();

如果我們并不需要訪(fǎng)問(wèn)鍵-值對(duì),可以直接忽略 next()和 previous()函數(shù)的返回值,而是調(diào)用 key()和 value()函數(shù)即可,如:


QMapIterator<QString, int> i(map); 
while (i.hasNext()) { 
        i.next(); 
        if (i.value() > largestValue) { 
                largestKey = i.key(); 
                largestValue = i.value(); 
        } 
}

Mutable 遍歷器則可以修改 key 對(duì)應(yīng)的值:


QMutableMapIterator<QString, int> i(map); 
while (i.hasNext()) { 
        i.next(); 
        if (i.value() < 0.0) 
                i.setValue(-i.value()); 
}

如果是 STL 風(fēng)格的遍歷器,則可以使用它的 key()和 value()函數(shù)。而對(duì)于 foreach 循環(huán),我們就需要分別對(duì) key 和 value 進(jìn)行循環(huán)了:


QMultiMap<QString, int> map; 
... 
foreach (QString key, map.keys()) { 
        foreach (int value, map.values(key)) { 
                doSomething(key, value); 
        } 
}

本文出自 “豆子空間” 博客,請(qǐng)務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/193918