深度解析 QMap 與 QHash
阿新 • • 發佈:2019-02-16
1、QMap深度解析
- QMap 是一個以升序鍵儲存鍵值對的資料結構
- QMap 原型為class QMap<K, T>
模板
- QMap 中的鍵值對根據 Key 進行了排序
- QMap 中的Key型別必須過載 operator <
2、QMap的使用示例
示例1:QMap<QString, int> map; map.insert("Key 2", 2); map.insert("Key 0", 0); map.insert("Key 1", 1); for(int i=0; i<3; i++) { qDebug() << map.value("Key " + QString::number(i)); } QList<QString> list = map.keys(); for(int i=0; i<list.count(); i++) { qDebug() << list[i]; }
示例2:
QMap<QString, int> map; map["Key 2"] = 2; map["Key 0"] = 0; map["Key 1"] = 1; for(int i=0; i<3; i++) { qDebug() << map["Key " + QString::number(i)]; } QMapIterator<QString, int> it(map); // it指向的是第一個元素之前的位置 while( it.hasNext() ) { it.next(); qDebug() << it.key() << " : " << it.value(); }
(QMapIterator<QString, int> it(map); 定義一個QMap的迭代器it,這句話之後,it指向QMap元素的前一個位置。在while迴圈裡面,判斷it的下一個位置是否為空,然後進行具體操作。)
3、QMap的注意事項
- 通過Key獲取Value的時候:
- - 當Key存在,返回對應的Value
- - 當Key不存在,返回值型別對應的“零”值
- 插入鍵值對時:
- - 當Key存在,更新Value的值
- - 當Key不存在,插入新的鍵值對
4、QHash深度解析
- QHash是Qt中的雜湊資料結構
- - QHash原型為class QHash<K, T>
- - QHash中的鍵值對在內部無序排列
- - QHash中的Key型別必須過載 operator ==
- - QHash中的Key物件必須過載全域性雜湊函式qHash()
5、QHash使用示例
QHash<QString, int> hash;
hash["Key 2"] = 2;
hash["Key 3"] = 3;
hash["Key 1"] = 1;
for(int i=1; i<4; i++)
{
qDebug() << hash["Key " + QString::number(i)];
}
hash.insert("Key 0", 0);
QHash<QString, int>::const_iterator i;
for(i=hash.constBegin(); i!=hash.constEnd(); ++i)
{
qDebug() << i.key() << " : " << i.value();
}
(QHash其實在使用上和QMap是一樣一樣的!) 上面結果為1 2 3 ,是因為根據key 1 key 2 key 3 的順序來訪問的。 下面正好是順序的,但是並不能說明什麼?
6、QMap和QHash對比分析
- QMap和QHash的介面相同,可以直接替換使用
- -QHash的查詢速度明顯快於QMap
- -QHash佔用的儲存空間則明顯多於QMap
- - QHash以任意的方式儲存元素
- - QMap以Key順序儲存元素
- - QHash的鍵型別必須提供operator ==()和qHash(key)函式
- - QMap的鍵型別必須提供operator <()函式
7、NotePad程式設計實驗
問題描述:NotePad記事本有一個小BUG,就是在儲存檔案的時候,如果沒有指定儲存檔案的字尾的時候,儲存的檔案就沒有後綴名。 問題解決:使用QMap或者QHash,由於要求不高,所以我們就是用QMap 問題一定為QString MainWindow::showFileDialog(QFileDialog::AcceptMode mode, QString title)
{
QString ret = "";
QFileDialog fd(this);
QStringList filters;
filters.append("Text Files (*.txt)");
filters.append("All Files (*)");
fd.setWindowTitle(title);
fd.setAcceptMode(mode);
if( mode == QFileDialog::AcceptOpen )
{
fd.setFileMode(QFileDialog::ExistingFile);
}
fd.setFilters(filters);
if( fd.exec() == QFileDialog::Accepted )
{
ret = fd.selectedFiles()[0];
}
return ret;
}
由於ret = fd.selectedFiles()[0];儲存的檔案不含有後綴名,所以我們需要判斷,如果使用者在輸入儲存的檔名的時候,如果沒有輸入檔案字尾名則自動為其加上字尾名,如果加了就什麼都不做。那麼應該怎麼做呢?這就需要用到QMap或者QHash了,因為他們儲存的是鍵值對,正好可以將filters和字尾名對應上,方便為沒加上字尾名的檔案自動加上字尾名。
具體程式碼:
QString MainWindow::showFileDialog(QFileDialog::AcceptMode mode, QString title)
{
QString ret = "";
QFileDialog fd(this);
QStringList filters;
QMap<QString, QString> map;
const char* filterArray[][2] = // 定義鍵值對的二維陣列
{
{"Text Files (*.txt)", ".txt"},
{"All Files (*)", "*" },
{NULL, NULL }
};
for(int i=0; filterArray[i][0]!=NULL; i++)
{
filters.append(filterArray[i][0]); // 新增filters
map.insert(filterArray[i][0], filterArray[i][1]); // 關聯QMap的鍵值對
}
fd.setWindowTitle(title);
fd.setAcceptMode(mode);
fd.setFilters(filters);
if( mode == QFileDialog::AcceptOpen )
{
fd.setFileMode(QFileDialog::ExistingFile);
}
if( fd.exec() == QFileDialog::Accepted )
{
ret = fd.selectedFiles()[0];
if( mode == QFileDialog::AcceptSave ) // 如果是儲存模式的話,才需要自動新增字尾
{
QString postfix = map[fd.selectedFilter()];// 得到選擇的檔案的字尾
if( (postfix != "*") && !ret.endsWith(postfix) ) // 如果字尾不是*,並且ret的字尾不是postfix的話
{
ret = ret + postfix;
}
}
}
return ret;
}
問題結果:小BUG解決!!