1. 程式人生 > >深度解析 QMap 與 QHash

深度解析 QMap 與 QHash

1、QMap深度解析

  • QMap 是一個以升序鍵儲存鍵值對的資料結構
  • QMap 原型為class QMap<K, T> 模板
  • QMap 中的鍵值對根據 Key 進行了排序
  • QMap 中的Key型別必須過載 operator <
微笑往QMap裡面插入的資料,會自動根據key值得大小按照升序的方式自動排序,並且QMap的每個元素是一個鍵值對,即一個鍵值key對應一個值value。)

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解決!!