一文帶你深入了解Qt中的順序容器類(lèi)與關(guān)聯(lián)容器類(lèi)
前言
眾所周知,C++中存在很多容器類(lèi)。同樣,Qt中也有很多容器類(lèi),而且Qt中的容器類(lèi)在存取速度、內(nèi)存開(kāi)銷(xiāo)等方面進(jìn)行了優(yōu)化,使用起來(lái)更輕量級(jí)、更便捷還有很重要的一點(diǎn)--它們是線程安全的。
具體介紹容器之前,先要了解 Qt容器的一個(gè)特性。Qt容器類(lèi)都是基于模板的類(lèi),比如常用的OList<T>,這里的T表示的就是具體的類(lèi)型,而且必須是可賦值的數(shù)據(jù)類(lèi)型。這意味著該數(shù)據(jù)類(lèi)型必須提供一個(gè)默認(rèn)的構(gòu)造函數(shù)、賦值構(gòu)造函數(shù)和賦值運(yùn)算符。所以,像int、double、QString、QTime等類(lèi)型可以存儲(chǔ)到容器中,而QObiect及其他一些子類(lèi)如QWidget、QDialog等無(wú)法直接存儲(chǔ)到容器中,但是可以使用指針類(lèi)型進(jìn)行替代,如OList<OButton*>list。
基于不同的底層數(shù)據(jù)結(jié)構(gòu),可以將容器類(lèi)分為兩類(lèi):順容器類(lèi)和關(guān)聯(lián)容器類(lèi)。
1.順序容器類(lèi)
Qt中的順序容器類(lèi)有QList、QLinkedList、QVector、QStack和QQueue,每個(gè)類(lèi)中都有大量的API。在講解的時(shí)候,只重點(diǎn)介紹比較有代表性的,對(duì)于其他更多API的用法,可以查閱官方幫助文檔來(lái)進(jìn)行拓展。
1.1QList
QList是十分常用的容器類(lèi),它是以數(shù)組列表的形式實(shí)現(xiàn)的,可以理解為它就是C中的數(shù)組。QList以索引的方式對(duì)數(shù)據(jù)項(xiàng)進(jìn)行訪問(wèn),其查找數(shù)據(jù)速度以及在尾部操作數(shù)據(jù)的速度,都是非常快的。
QList中用于添加、插人、查詢、替換、移動(dòng)、刪除數(shù)據(jù)項(xiàng)的函數(shù)有append()、prepend()、insert()、contains()、replace()、move()、swap()、removeAt()removeFirst(、removeLast()和clear()等:
OList<QString> list; // 添加元素 list.append("one"); list << "Two" << "Four"; list.insert(2,"Three"); //根據(jù)索引值訪問(wèn)元素 Rstring v=list[0] //等價(jià)于 list.at(0) // 查詢?cè)? bool has = list.contains("one"); // 替換 list.replace(0,"zero"); // 交換 list.swap(0,1); // 移動(dòng) list.move(0,1); // 刪除 list.removeat(0)list.removeLast(); list.clear();
1.2QLinkedList
QLinkedList是鏈?zhǔn)搅斜?,其?shù)據(jù)項(xiàng)基于非連續(xù)內(nèi)存存儲(chǔ),也就是數(shù)據(jù)結(jié)構(gòu)中的鏈?zhǔn)酱鎯?chǔ),鑒于該特點(diǎn),其插入和刪除數(shù)據(jù)的效率非常高。
相關(guān)API的用法同QList幾乎一致,不贅述。有一點(diǎn)需要注意,QLinkedList不提供基于索引值的對(duì)外接口。
1.3QVector
QVector<T>是一個(gè)提供動(dòng)態(tài)數(shù)組的模板類(lèi)
QVector 是 Qt 的通用容器類(lèi)之一。它將其數(shù)據(jù)項(xiàng)存儲(chǔ)在相鄰的內(nèi)存位置,并提 供 基 于 索 引 的 快 速 訪 問(wèn)。QVector 提 供 了 與 QList 類(lèi) 似 的 API 和 功 能, 同 樣 不贅述。但有一點(diǎn)需要注意,QVector<T> 通常比 QList<T> 具有更好的性能,因?yàn)?QVector<T> 總是將其數(shù)據(jù)項(xiàng)存儲(chǔ)在內(nèi)存中。
1.4 QStack
Stack 是提供類(lèi)似于堆棧的后進(jìn)先出(Last In First Out, LIFO)操作的容器類(lèi),主要提供了 push() 和 pop() 兩個(gè)接口函數(shù)。
#include <QStack> QStack<int> stack; stack.push(1); stack.push(2); stack.push(3); while (!stack.isEmpty()) // 基于后進(jìn)先出的規(guī)則,會(huì)輸出 3 2 1 cout << stack.pop() << endl;
1.5QQueue
QQueue 是提供類(lèi)似于隊(duì)列先進(jìn)先出(First In First Out, FIFO)操作的容器類(lèi)。主要提供了 enqueue() 和 dequeue() 兩個(gè)接口函數(shù)。
QQueue<int> queue; queue.enqueue (1); queue.enqueue(2); queue.enqueue (3); while (!queue.isEmpty()) // 基于先進(jìn)先出的規(guī)則,會(huì)輸出 1 2 3 qDebug() << queue.dequeue() << endl
2.關(guān)聯(lián)容器類(lèi)
2.1QSet
QSet 是基于散列表的集合模板類(lèi)。作為一個(gè)簡(jiǎn)單的容器,它跟 QList 很像,不過(guò)有一點(diǎn)需要特別注意,由于它底層的數(shù)據(jù)結(jié)構(gòu)是基于散列表的,存儲(chǔ)進(jìn)來(lái)的數(shù)據(jù)是無(wú)序的。對(duì)于散列,有一個(gè)很重要的嘗試就是,可以在散列表中非??斓夭檎业侥繕?biāo)值。還有一點(diǎn)需要注意,QSet 內(nèi)部是用 QHash 實(shí)現(xiàn)的。
QSet<QString>set; // 添加 set << "A" << "B" << "C"; // 插入 set.insert("D"); // 每次輸出,元素順序都不同,因?yàn)?hash 值每次都不同 qDebug() << set;qDebug() << set.count(); // 判斷 if (!set.isEmpty() && set.contains("D")){ set.remove("D"); } qDebug() << set; // 獲取所有值 QList<QString>list = set.values(); qDebug() << list; // 轉(zhuǎn)換成 QListlist = set.toList(); qDebug() << list
2.2QMap
QMap<Key, T> 以映射的方式完成數(shù)據(jù)存儲(chǔ),Key 對(duì)應(yīng) T,成對(duì)出現(xiàn)。對(duì)于 Key的類(lèi)型,一般情況下使用 QString 來(lái)表示,因?yàn)樗幸粋€(gè)硬性要求,就是 Key 必須是可進(jìn)行哈希運(yùn)算的。QMap 存儲(chǔ)數(shù)據(jù)會(huì)按照鍵的順序,這是因?yàn)樵诘讓硬捎昧斯1?+ 鏈表的組合結(jié)構(gòu),這會(huì)導(dǎo)致存取速度下降。如果只看中速度而不在乎存儲(chǔ)順序,可以使用 QHash。
QMap<QString,int> map; // 添加數(shù)據(jù) map["one"] = 1; map["two"] = 2; // 插入數(shù)據(jù) map.insert("three",3); qDebug() << map; // 通過(guò) key 獲取對(duì)應(yīng)的數(shù)據(jù) int num = map["one"]; qDebug() << num; // 通過(guò) key 獲取對(duì)應(yīng)數(shù)據(jù)的其他方式 num = map.value("two"); qDebug() << num; // 根據(jù) key 刪除數(shù)據(jù) map.remove("one"); // 根據(jù) key 獲取對(duì)應(yīng)的值,如果沒(méi)有這個(gè) key,則得到后邊給出的默認(rèn)值 num = map.value("one",0); qDebug() << num; // 獲取所有的 k eysQList<QString>keys = map.keys(); qDebug() << keys; // 獲取所有的 valuesQList<int> values = map.values(); qDebug() << values
2.3QMultiMap
MultiMap 是 QMap 的子類(lèi),是用于處理多值映射的便利類(lèi)。多值映射就是一個(gè)鍵可以對(duì)應(yīng)多個(gè)值。QMap 正常情況下不允許多值映射,除非使用QMap::insertMulti() 添加鍵值對(duì)?;诶^承關(guān)系的存在,QMap 的大多數(shù)函數(shù)在 QMultiMap 都是可用的, 但是有幾個(gè)特殊的函數(shù)需要關(guān)注QMultiMap::insert() 等效于 QMap::insertMulti(),QMultiMap::replace() 等效于 QMap::insert()。
QMultiMap<QString, int> map1, map2, map3; map1.insert("A", 10); // 再次插入鍵值對(duì),等于是字典中有兩個(gè)鍵值對(duì) map1.insert("A", 20); // map1.size() == 2 qDebug() << map1; map2.insert("A", 30); // map2.size() == 1 qDebug() << map2; // 支持 + 完成拼接 map3 = map1 + map2; // map3.size() == 3 qDebug() << map3; // 只能得到最新插入的值,而且不支持以 d[key] 的方式訪問(wèn)數(shù)據(jù) qDebug() << map3.value("A")
2.4 QHash
QHash 是基于散列表來(lái)實(shí)現(xiàn)字典功能的模板類(lèi),QHash<Key,T> 存儲(chǔ)的鍵值對(duì)具有非??斓牟檎宜俣?。QHash 與 QMap 的功能和用法相似,區(qū)別在于以下幾點(diǎn)。
QHash 比 QMap 的查找速度快。
在 QMap 上遍歷時(shí),數(shù)據(jù)項(xiàng)是按照鍵排序的,而 QHash 的數(shù)據(jù)項(xiàng)是按照任意順序排列的。
QMap 的鍵必須提供“<”運(yùn)算符,QHash 的鍵必須提供“==”運(yùn)算符和一個(gè)名稱(chēng)為 qHash() 的全局散列函數(shù)。
到此這篇關(guān)于一文帶你深入了解Qt中的順序容器類(lèi)與關(guān)聯(lián)容器類(lèi)的文章就介紹到這了,更多相關(guān)Qt容器類(lèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一篇文章帶你了解C++(STL基礎(chǔ)、Vector)
這篇文章主要為大家詳細(xì)介紹了C++ STL基礎(chǔ),vector向量容器使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來(lái)幫助2021-08-08C語(yǔ)言數(shù)據(jù)類(lèi)型和格式說(shuō)明符基礎(chǔ)教程示例
這篇文章主要為大家介紹了C語(yǔ)言數(shù)據(jù)類(lèi)型和格式說(shuō)明符基礎(chǔ)教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12C語(yǔ)言 設(shè)計(jì)模式之訪問(wèn)者模式
這篇文章主要介紹了C語(yǔ)言 設(shè)計(jì)模式之訪問(wèn)者模式的相關(guān)資料,需要的朋友可以參考下2017-01-01淺析char 指針變量char *=p 這個(gè)語(yǔ)句的輸出問(wèn)題
下面小編就為大家?guī)?lái)一篇淺析char 指針變量char *=p 這個(gè)語(yǔ)句的輸出問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05c++如何將一個(gè)char轉(zhuǎn)化為string
這篇文章主要介紹了c++如何將一個(gè)char轉(zhuǎn)化為string問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08