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