Qt容器(QMap/QHash 等)使用详解

一、Qt容器的遍历器

Qt 的容器类提供了两种风格的遍历器:Java 风格和 STL 风格。

每一种容器都有两种 Java 风格的遍历器:一种提供只读访问,一种提供读写访问:

容器

只读遍历器

读写遍历器

QList,QQueue

QListIterator

QMutableListIterator

QLinkedList

QLinkedListIterator

QMutableLinkedListIterator

QVector,QStack

QVectorIterator

QMutableVectorIterator

QSet

QSetIterator

QMutableSetIterator

QMap,QMultiMap

QMapIterator

QMutableMapIterator

QHash,QMultiHash

QHashIterator

QMutableHashIterator

 

STL 风格的遍历器

STL 风格的遍历器从 Qt 2.0 就开始提供。这种遍历器能够兼容 Qt 和 STL 的通用算法,并且为速度进行了优化。同 Java 风格遍历器类似,Qt 也提供了两种 STL 风格的遍历器:一种是只读访问,一种是读写访问。我们推荐尽可能使用只读访问,因为它们要比读写访问的遍历器快一些。

容器

只读遍历器

读写遍历器

QList,QQueue

QList::const_iterator

QList::iterator

QLinkedList

QLinkedList::const_iterator

QLinkedList::iterator

QVector,QStack

QVector::const_iterator

QVector::iterator

QSet

QSet::const_iterator

QSet::iterator

QMap,QMultiMap

QMap::const_iterator

QMap::iterator

QHash,QMultiHash

QHash::const_iterator

QHash::iter

二、QMap和QHash的对比分析

QMap和QHash的接口相同,可直接替换使用,它们之间的差异如下:

(1)、QHash的查找速度明显快于QMap

(2)、QHash占用的存储空间明显多于QMap

(3)、QHash以任意的方式存储元素

(4)、QMap以Key顺序存储元素

(5)、QHash如果使用自定义类型作为主键,QHash的键类型必须提供operator == () 和 qHash(key)函数

(6)、QMap如果使用自定义类型作为主键,QMap的键类型必须提供operator <函数

 

三、使用实例

#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 

struct Student
{
    QString name;
    int no;

    bool operator <(const struct Student& other) const
    {
        if (name < other.name)
        {
            return true;
        }
        else if (name == other.name)
        {
            return no < other.no;
        }

        return false;
    }
};

class Employee
{
public:
    Employee() {}
    Employee(const QString &name, const QDate &dateOfBirth){myName = name;myDateOfBirth = dateOfBirth;}
    const QString name(){return myName;}
    const QDate dateOfBirth(){return myDateOfBirth;}

    inline bool operator==(const Employee &other) const
    {
        return (myName==other.myName && myDateOfBirth==other.myDateOfBirth);
    }
    //以下的写法是错误的//error: passing 'const Employee' as 'this' argument of 'const QString Employee::name()' discards qualifiers
    /*inline bool operator==(const Employee &other) const
    {
        return myName == other.name()
               && myDateOfBirth == other.dateOfBirth();
    }*/

public:
    QString myName;
    QDate myDateOfBirth;
};

//以下的写法是错误的://error: passing 'const Employee' as 'this' argument of 'const QString Employee::name()' discards qualifiers
/*inline uint qHash(const Employee &key)
{
    return qHash(key.name()) ^ key.dateOfBirth().day();
}*/

inline uint qHash(const Employee key)
{
    //^ -----按位异或(Xor)是一种可逆运算符,只有在两个比较的位不同时其结果是1,否则结果为0。
    return qHash(key.myName) ^ key.myDateOfBirth.day();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //----------------Java 风格的遍历器
    /*每一种容器都有两种 Java 风格的遍历器:一种提供只读访问,一种提供读写访问:
    容器                                 只读遍历器                读写遍历器
    QList,QQueue                  QListIterator        QMutableListIterator
    QLinkedList                      QLinkedListIterator  QMutableLinkedListIterator
    QVector,QStack                QVectorIterator      QMutableVectorIterator
    QSet                             QSetIterator         QMutableSetIterator
    QMap,QMultiMap      QMapIterator         QMutableMapIterator
    QHash,QMultiHash    QHashIterator        QMutableHashIterator
    */
    //----------------end Java 风格的遍历器
    //------QMap
    QMap id2NameMap;
    id2NameMap.insert(2,"name2");
    id2NameMap.insert(1,"name1");
    id2NameMap.insert(3,"name3");
    qDebug()< it1(id2NameMap);
    while (it1.hasNext())
    {
        it1.next();
        if(2 == it1.key())
        {
            qDebug() << it1.value();
        }
    }

    //读写遍历器
    QMutableMapIterator mit1(id2NameMap);
    while (mit1.hasNext())
    {
        mit1.next();
        if(2 == mit1.key())
        {
            mit1.setValue("name2new");
            qDebug() << mit1.value();
        }
    }
    qDebug()<,QQueue                  QList::const_iterator        QList::iterator
    QLinkedList                      QLinkedList::const_iterator  QLinkedList::iterator
    QVector,QStack                QVector::const_iterator      QVector::iterator
    QSet                             QSet::const_iterator         QSet::iterator
    QMap,QMultiMap      QMap::const_iterator    QMap::iterator
    QHash,QMultiHash    QHash::const_iterator   QHash::iter
     */

    //------QHash
    QHash id2NameHash;
    id2NameHash.insert(2,"hashName2");
    id2NameHash.insert(1,"hashName1");
    id2NameHash.insert(3,"hashName3");
    qDebug()<::const_iterator rIt1;
    for (rIt1 = id2NameHash.begin(); rIt1 != id2NameHash.end(); ++rIt1)
    {
        if(2 == rIt1.key())
        {
            qDebug() << rIt1.value();
        }
    }
    //读写遍历器
    QHash::iterator wIt1;
    for (wIt1 = id2NameHash.begin(); wIt1 != id2NameHash.end(); ++wIt1)
    {
        if(2 == wIt1.key())
        {
            //修改内容
            *wIt1 = "hashName2new";// 使用 * 运算符获取遍历器所指的元素
            qDebug() << wIt1.value();
        }
        else if(3 == wIt1.key())
        {
            //修改内容
            id2NameHash.insert(3,"hashName3new");
            qDebug() << wIt1.value();
        }
    }
    qDebug()< key2NameMap;
    Student tmp;
    tmp.no = 2;
    tmp.name = "name2";
    key2NameMap.insert(tmp,"name2");
    tmp.no = 1;
    tmp.name = "name1";
    key2NameMap.insert(tmp,"name1");
    tmp.no = 3;
    tmp.name = "name3";
    key2NameMap.insert(tmp,"name3");
//    qDebug()<::iterator cusIt1 = key2NameMap.find(find);
    if(cusIt1 != key2NameMap.end())
    {
        qDebug()<<"I can find";
    }
    else
    {
        qDebug()<<"I can not find";
    }
    //------end 自定义 QMap的Key类型

    //------自定义 QHash的Key类型
    QHash customHash;
    customHash.insert(Employee("name1", QDate(2018,10,21)),"name1");
    customHash.insert(Employee("name3", QDate(2018,10,23)),"name3");
    customHash.insert(Employee("name2", QDate(2018,10,22)),"name2");
    customHash.insert(Employee("name7", QDate(2018,10,27)),"name7");
    //只读遍历器
    QHash::const_iterator rIt2;
    for (rIt2 = customHash.begin(); rIt2 != customHash.end(); ++rIt2)
    {
        qDebug() << rIt2.key().myName << ":" << rIt2.value();
    }
    //------end 自定义 QHash的Key类型


    MainWindow w;
    w.show();

    return a.exec();
}

 

 

你可能感兴趣的:(QT,C/C++)