qt几种常用容器的理解和使用

前言

本文整理了对qt几种容器的理解和用法,主要包括:QVector、QList、QLinkedList、QByteArray、QVariant、QSet、QMap、QHash。

1.QVector
1.1 理解:

是对所有数组的封装,例如想创建一个数组,可以写成QVector array(5),
也可以写成QVector array,就是说数组大小可以预先定义也可以先不定义。不论是否有定义,都可以使用array.count()或者array.size()获取到数组元素的个数。
QVector使用的是连续的内存空间,针对不改变的对象,即只要求查询,不做插入删除等操作效率高,但是由于自身结构的原因,插入删除甚至包括追加等操作的效率会比QLIst低。

1.2 使用:

1)头文件包含:
#include<QVector>

2)QVector array 赋值和获取跟int array[10]一样处理即可
3)添加元素:
方式1:

	QVector<QString> strArray;
	strArray.append("AAA"); 

方式2:

QVector<QString> strArray;
strArray<<"BBB";  //可以这样
strArray<<"MyName"<<"is"<<"LEO";//也可以这样加上个元素

4)插入:

strArray.insert(1,"YYY");

5)删除:

 	strArray.remove(1); //删除第一个元素,从0开始
   	strArray.remove(1,3); //从1开始,删除3个元素
	strArray.pop_back();   // 删除末尾元素    
    strArray.pop_front();   // 删除开始位置元素

6)替换

strArray.replace(1,"LEO");

7)遍历

方式1:

QVector<double> vect(2); 
vect[0] = 1.0; 
vect[1] = 2.0; 
for (int i = 0; i < vect.count(); ++i) {
 qDebug() << vect[i]; 
}

方式2:
QVector vect(2);
for(auto a = vect.begin(); a != vect.end(); a++){
qDebug() << *a;
}

方式3:使用迭代器

QVector<QString>::iterator iter;  
for (iter=strArray.begin();iter!=strArray.end();iter++)  
{  
	qDebug() <<  *iter << "\0";
}  

上述,除了append()和replace()这两个函数外,其它函数会比较慢,
因为在内存中移动一个位置时,这些函数会使向量容器内的对象要移动许多次.

1.3 其他接口说明:

1)调用at()函数来读取对象会比使用operator读取速度更快
2)contains()函数是用来查找向量容器内是否含有某个对象
3)resize()函数可以在任何时候改变QVector向量容器的体积
4)QVector会预先分配两倍于实际数据的大小空间,从而减少再分配的次数
5)reserve()函数,如果你事先知道向量容器大概包含多少个对象,你可以调用这个函数来预先分配一定的内存大小空间
6)capacity()函数会告诉你向量容器所占内存的实际大小空间

2.QList
2.1 理解:

QList 是基于数组+链表,即各个节点的 指针不是通过Next来指向,而是通过将各节点的指针存放在一个数组中,遍历通过找到数组中的指向该节点的指针,再通过指针将节点找到. 相比QVector, QList采用的是分散存储,查找效率跟QVector差不多,也可用于插入、删除等操作,所以一般推荐如果不是强制要求使用QVector,优先选择QList。

2.2 使用:

1)添加
方式1:

QList<QString> List;
List << "AAA" <<  "BBB";

方式2:

List.append("CCC"); //尾部添加
List.push_back("CCC"); 

List.prepend("DDD"); //头部添加
List.push_front("DDD"); 

2)删除
方式1:

QString str = List.takeAt(2); // 从列表中删除第3个元素,并获取它

方式2:

List.removeAt(2);// 从列表中删除第3个元素

方式3: 根据内容进行删除

QList<QString> list;
list << "sun" << "cloud" << "sun" << "rain";
list.removeOne("sun");

3)修改

QList<QString> list;
list << "AAA" << "BBB" << "CCC";
list.replace(1, "DDD");//参数1 元素下标, 参数2 修改的结果值

4)改变位置

list.swap(1,3);//交换位置1和位置3的元素
list.move(1,4);//把第一个元素移到第四个元素,其他元素顺移

5)查找

方式1:

int index = list.indexOf("mm");//返回该元素的下标值

方式2:

bool isCon = list.contains("23");//列表是否有某元素 成功返回true 否则false

其他:

index = list.count();//列表总元素 同list.length();
index = list.count("AAA");//列表中有几个这样的元素

6)遍历访问

方式1:

for(int i = 0; i < list.size(); ++i) {
   //at()操作比操作符[]更快,因为它不需要深度复制
   qDebug() << list[i] << list.at(i) << list.value(i) ;
}

方式2:
使用迭代器

QList<QString>::iterator it;
for(it=list.begin(); it!=list.end();++it)
{
    if((*it)== "00")
    {
        it = list.erase(it,it+2);//删除从起始位置到结束位置的元素
    }
    qDebug() << "it" << (*it);
}
3.QLinkedList
3.1 理解:

对于大多数目的,QList是使用的正确类。它的基于索引的API比QLinkedList的基于迭代器的API更方便,并且由于其将项存储在内存中的方式,它通常比QVector更快. 但是,如果您需要一个真正的链表,并且要用来保存大量数据和保证在列表中间不断插入时间,迭代器可以迭代项而不是索引,请使用QLinkedList。

3.2 使用:

1)添加
方式1:

QLinkedList<QString> Listl;
List << "AAA" << "BBB" << "CCC";

方式2:

QLinkedList<QString> List;
list.append("aaa"); //链表尾部插入
list.push_back("aaa"); //链表尾部插入

list.push_front("5");//链表表头插入

2)删除
方式1:

QLinkedList<QString> List;
list << "sun" << "cloud" << "sun" << "rain";
list.removeOne("sun");

list.removeFirst();
list.removeLast();
list.clear();

3)遍历

QLinkedList<QString> list;
list<<"1"<<"2"<<"3"<<"4";
// foreach正序:
QString str;
foreach (str, list)
	qDebug() << str;
	
// 迭代器正序
QLinkedList<QString>::iterator it;
for(it = list.begin(); it != list.end(); ++it){
    qDebug() << *it;
}

// 迭代器倒序
QLinkedList<QString>::const_iterator it = list.constEnd();
while (it != list.constBegin())
{
	--it;
	qDebug()<<*it;
}

4.QByteArray
4.1 理解:

有两种情况下会比较适合使用QByteArray,第一就是要存储纯二进制数据(raw binary data)(原始数据)或8-bit编码文本字符串.

4.2 使用:
  1. 访问

    QByteArray的访问方式有四种:[]、data[]和at()、constData[]。其中[]和data[]为可读可写;at()和constData[]为只读,因此访问用这两种速度较快。

    跟C++的普通数组一样,也可以使用 [] 来访问其具体下表对应的字节,对于非const的 QByteArray,可以直接进行赋值:

QByteArray ba;
ba.resize(3);
ba[0] = 0x30;
ba[1] = 0x31;
ba[2] = 0x32;
qDebug() << ba.toHex(); //return “303132”

QByteArray array2("hello world");
qDebug() << array2.data()[0] << array2.data()[1] << array2.data(); //结果:h e hello world

对于只读操作,请使用“at( )“,因为它可以避免深拷贝,比使用“[ ]“要快,效率要高

qDebug() << array.at(2);
  1. 查找
QByteArray x("sticky question");
QByteArray y("sti");
x.indexOf(y);               // returns 0
  1. 数据转换
QByteArray ba;
int n = 63;
ba.setNum(n); // ba == “63”
ba.setNum(n, 16); // ba == “3f”
  1. left、right、mid操作
  //left
  QByteArray x("Pineapple");
  QByteArray y = x.left(4);
  // y == "Pine"

  //right
  QByteArray x("Pineapple");
  QByteArray y = x.right(5);
  // y == "apple"

  //mid
  QByteArray x("Five pineapples");
  QByteArray y = x.mid(5, 4);     // y == "pine"
  QByteArray z = x.mid(5);        // z == "pineapples"
5.QVariant
5.1 理解:

QVariant类是Qt的共用体union数据类型,不仅能保存很多Qt类型的值,包括QColor,QBrush,QFont,QRect,QString及QSize等等,而且能存放Qt的容器类型值. 常用于存储不同的数据类型,可以在接口返回值中广泛使用。

5.2 使用:
  1. 定义一个int类型的QVariant
QVariant vNum(100);
qDebug() << vNum.toInt();

  1. 定义一个float类型的QVariant
QVariant vPI(3.14);
qDebug() << vPI.toFloat();
  1. 定义一个QString类型的QVariant
QVariant vStr("Hello!");
qDebug() << vStr.toString();
  1. 定义一个bool类型的QVariant
QVariant vBool(false);
qDebug() << vBool.toBool();
  1. 定义一个QColor类型的QVariant
QColor color = QColor(Qt::yellow);
QVariant vColor(color);
qDebug() << vColor.type();
qDebug() << vColor.value<QColor>();
6.QSet
6.1 理解:

基于哈希表实现的一种单值的数学集合的快速查找容器,使用方式与QList相同,但其内元素不会有重复。

6.2 使用:
  1. 插入
struct node  
{  
    int cx;
    QString str;  
}; 

QSet<node> ss;
for(i=0,j=100;i<101;i++,j--)  
{  
    temp.cx = i;  
    temp.cy = j;  
    ss.insert(temp);  
}  

  1. 遍历
QSet<node>::iterator iter;
for(iter=ss.begin();iter!=ss.end();++iter)  
{
	qDebug() << iter->cx << "  " << iter->cy;
}
        
7.QMap
7.1 理解:

基于红黑树算法的一套字典,它通过(Key, value)存储一对值,并通过Key可以查找与之关联的value的值,在QMap中,项总是按键排序。

7.2 使用:
  1. 插入

可以用运算符[ ]插入一对 (key,value) 到QMap对象中:

QMap<QString, int> map;
map["one"] = 1;
map["three"] = 3;
map["seven"] = 7;

也可以使用函数insert() 插入:

QMap<QString, int> map;
map.insert("twelve", 12);
  1. 查询

获取值:

int num1 = map["thirteen"];
 int num2 = map.value("thirteen");

查看QMap对象中是否包含某一项:

int timeout;
if (map.contains("TIMEOUT"))
	timeout = map.value("TIMEOUT");
  1. 遍历

查看键值:

QMap<QString, int> map;
map["one"] = 1;
map["three"] = 3;
QMapIterator<QString, int> i(map);
while (i.hasNext()) {
     i.next();
     cout << i.key() << ": " << i.value() << endl;
 }

只查看值:

QMap<QString, int> map;
 ...
 foreach (int value, map)
     cout << value << endl;
  1. 删除
 //方式1    
 int i = m_qMap.remove("one");//i=1;
 int b = m_qMap.remove("trg");//b=0;

 //方式2 
 it=m_qMap.find("one");
 m_qMap.erase(it);//it是迭代器
8.QHash
8.1 理解:

和QMap不同的是,QHash中的键值对不会进行自动排序,而是根据Hash值存储。QHash中每个键只允许一个值,它提供比QMap更快的查找,但所需空间更大。在QHash中,键值是任意排序,不像QMap默认按照键值升序排序。

8.2 使用:
  1. 插入
	QHash<int,QString> qhash;
     //方式一
     qhash[1] = "1";
     qhash[2] = "2";
     qhash[3] = "3";
 
     //方式二
     qhash.insert(4, “4”);
  1. 获取值
 
    //方式一   
    QString str1=qhash.value(1);//str1="1";
 
    //方式二
    QString str2=qhash[2];//str1="2";

  1. 查找
     QString str;
    if(qhash.contains(1))
    {
        str=qhash.value(1);      
    }
  1. 遍历
QHash<int,QString>::const_iterator it = qhash.constBegin();
while (it != qhash.constEnd()) {
    qDebug() << it.key() << ": " << it.value();
    ++i;
	if(it.value() == "aaa")
	{
		qhash.erase(it);//删除
	}
}
  1. 删除
    qhash.erase(it);//在迭代器中使用
 
    qhash.remove(key);
  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅笑一斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值