Qt容器類QList、QLinkedList和QVector類

羅三炮炮發表於2020-11-11

QList< T >是迄今為止最常用的容器類,它儲存給定資料型別T的一系列數值,相對於其他Qt容器類,QList被高度優化。QList< T >維護了一個指標陣列,該陣列儲存的指標指向QList< T >儲存的列表項的內容。因此它提供了基於下標的快速訪問。
對於不同的資料型別,QList採取不同的儲存策略:

  1. 如果T是一個指標型別或指標大小的基本型別(即該型別所佔的位元組數和指標型別所佔的位元組數相同),QList會直接將數值儲存在它的陣列中。
  2. 如果儲存物件的指標,則該指標指向實際儲存的物件。
#include <QCoreApplication>
#include<QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QList<QString> list;
    {
        QString str("This is a test string ");
        qDebug() << &str;
        list<<str;
    }
    qDebug() << &list[0];
    //此時QList儲存了str物件的一個複製
    qDebug()<<list[0] << "How are you";

    return a.exec();
}
/*
0x65fd60
0xee3ad0
"This is a test string " How are you
*/

QLinkedList類

QLinkedList< T >是一個連結串列,它是以非連續的記憶體儲存資料。它不能使用下標,只能使用迭代器訪問資料項。與QList相比,它在插入和刪除操作時具有更高的效率。

QVector類

QVector< T >在相鄰的記憶體中儲存給定的資料型別T的一組資料。在QVector中做插入操作速度很慢,因為這樣的操作將導致記憶體中大量的資料被移動。它既可以使用下標訪問資料項,也可以使用迭代器訪問資料項。

STL風格迭代器

對於每個容器類,Qt都提供了兩種型別的STL風格的迭代器資料型別:

  • 只讀迭代器 ConstIterator
  • 讀寫迭代器 iterator
    由於只讀迭代器的執行速度比讀寫迭代器的執行速度快,所以儘可能使用只讀型別。
#include <QCoreApplication>
#include<QDebug>
int main(int argc, char *argv[])
{
    QList<int> list;
    for(int j=0;j<10;j++){
        list.insert (list.end (),j);
    }
    // 讀寫迭代器
    QList<int>::Iterator i;
    for( i = list.begin (); i!=list.end ();i++){

        *i = (*i)+10;
        qDebug() << *i;
    }
    //只讀迭代器
    QList<int>::ConstIterator j;
    for( j = list.begin (); j!=list.end ();j++){
        qDebug() << *j;
    }

    return 0;
}

QMap類和QHash類

它們類似與C++STL中的map和unordered_map之間的關係,區別在於:

  • QHash具有更快的查詢速度
  • QMap總是按照鍵key的順序來儲存資料,而QHash則是無序的。
  • QHash的鍵型別key必須提供 operator==()和一個全域性的雜湊函式qHash(key)函式,而QMap的鍵key必須提供 operator < ()函式。
#include <QCoreApplication>
#include<QDebug>
#include <map>
int main(int argc, char *argv[])
{
    QMap<int,QString> map;
    //比C++中的插入操作更簡單,C++的插入需要用大括號包含鍵值對 {key,value}
    map.insert (1,"Mon");
    map.insert (3,"Wed");
    map.insert (2,"Tue");
    map.insert (4,"Thur");
    //建立一個只讀迭代器
    QMap<int,QString>::ConstIterator it;
    for(it = map.constBegin (); it != map.constEnd ();it++){
        //在C++中,使用first()和second()來表示鍵值對
        qDebug() << "key: "<<it.key()<<" value: "<<it.value ();
    }
    //讀寫迭代器
    QMap<int,QString>::Iterator find_it;
    //如果找不到,就返回end()
    find_it = map.find (3);
    if(find_it != map.end ()){
        find_it.value () = "WED";
    }
    qDebug() << "修改後:";
    for(it = map.constBegin (); it != map.constEnd ();it++){
        qDebug() << "key: "<<it.key()<<" value: "<<it.value ();
    }
    return 0;
}

QVariant類

QVariant類類似於C++的聯合(union)資料型別。它不僅能儲存很多Qt型別的值,包括QColor,QBrush、QFont…也能存放Qt的容器型別的值。Qt的很多功能都是建立在QVariant基礎上,如Qt的物件屬性及資料庫功能。

#include "widget.h"
#include<QVariant>
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QVariant v(709);
    qDebug() << v.toInt ();
    QVariant w("A Better Tomorrow");
    qDebug() << w.toString ();
    QMap<QString,QVariant> map;
    map["int"] = 709;
    map["double"] = 709.709;
    map["string"] = "You are THE BEST";
    map["color"] = QColor(255,0,0);
    //呼叫相應的轉換函式並輸出
    qDebug() << map["int"]<<map["int"].toInt ();
    qDebug() << map["double"]<<map["double"].toDouble ();
    qDebug() << map["string"]<<map["string"].toString ();
    qDebug() << map["color"]<<map["color"].value<QColor>();
    //建立一個字串列表
    QStringList sl;
    sl<<"A"<<"B"<<"C"<<"D";
    //將該列表儲存在一個QVariant變數中
    QVariant slv(sl);
    qDebug() << slv.type ();
    //判斷型別
    if(slv.type () == QVariant::StringList){
        QStringList list = slv.toStringList ();
        for(auto x:list){
            qDebug() << x;
        }
    }
}
/*
709
"A Better Tomorrow"
QVariant(int, 709) 709
QVariant(double, 709.709) 709.709
QVariant(QString, "You are THE BEST") "You are THE BEST"
QVariant(QColor, QColor(ARGB 1, 1, 0, 0)) QColor(ARGB 1, 1, 0, 0)
QVariant::QStringList
"A"
"B"
"C"
"D"
*/
Widget::~Widget()
{
}


相關文章