QT数据类型和容器用法

Qt库提供了基于通用模板的容器类, 这些类可用于存储指定类型的数据项,Qt中这些容器类的设计比STL容器更轻,更安全且更易于使用。容器类也都是隐式共的,它们是可重入的,并且已针对速度/低内存消耗和最小的内联代码扩展进行了优化,从而生成了较小的可执行文件。
容器类是基于模板的类,例如常用的QList<T>,T是一个具体的类,可以是int,float等简单类,也可以是QString、QDate类。T必须是一个可赋值的类型,即T必须提供一个默认构造函数,一个可复制的构造函数和一个赋值运算符。Qt的容器分为关联容器类和关联容器类, 顺序容器有:QList,QLinkedList,QVector,QStack和QQueue。
• QList是最适合使用的类型。它是作为数组列表实现的,提供了非常快的前置和追加操作。
• 如果需要一个链表,使用QLinkedList。
• 如果希望项目占据连续的内存位置,请使用QVector。
• QStack和QQueue是提供LIFO和FIFO语义的便捷类。

一,QT数据类型

QT基本数据类型定义在<QtGlobal>头文件中,QT基本数据类型

QT函数和宏定义,申明的宏使程序员能够向其应用程序添加编译器或平台特定的代码,而其他
宏则是用于较大操作的便捷宏, 比如Q_PROCESSOR_ARM,定义是否为ARM处理器编译应用
程序,Qt当前支持可选的ARM版本Q_PROCESSOR_ARM_V5,Q_PROCESSOR_ARM_V6和Q_PROCESSOR_ARM_V7。

返回值         函数                                 含义
T             qAbs(const T &t)                     绝对值函数
const T &     qMax(const T &a, const T &b)         检索两个给定对象的最大值
const T &     qMin(const T &a, const T &b)         检索两个给定对象的最小值

 1, QString:

它存储16位Unicode字符,字符串和数值之间的转换:

QString str7 = "56.5";
qDebug()<<str7.toInt();
qDebug()<<str7.toDouble();

qDebug()<<str7.toFloat();
qDebug()<<str7.toLong();
qDebug()<<QString::number(53);
qDebug()<<QString::number(4.4156);
qDebug()<<QString::number(4.4156,'f',2);
QString str8 = "F0F0";
bool OK;
int val = str8.toInt(&OK,16);
qDebug()<<val;
qDebug()<<QString::number(val,2);
qDebug()<<QString::number(val,8);
qDebug()<<QString::number(val,10);
qDebug()<<QString::number(val,16);


8位字符串和Unicode字符串之间转换,以QByteArray的形式返回字符串
qDebug()<<str8.toLocal8Bit();
qDebug()<<str8.toLatin1();
qDebug()<<str8.toUtf8();

 toLatin1() 返回 Latin-1(ISO 8859-1)编码的8位字符串。
• toUtf8() 返回UTF-8编码的8位字符串。UTF-8是US-ASCII(ANSI X3.4-1986)的超集,它
通过多字节序列支持整个 Unicode 字符集。
• toLocal8Bit() 使用系统的本地编码返回 8 位字符串。
QString 也提供了 fromLatin1(),fromUtf8() 和 fromLocal8Bit() 对应的转换函数。
字符串的拆分和拼接,除了前面提到的append(),prepend(),insert(),replace()和remove(),indexOf()或lastIndexOf() 以及trimped()和simplified()。

 QString字符分割

(1)QString截取一段字符串

在QString中,可以使用mid方法来截取一段指定长度的字符串。mid方法接收两个参数,第一个参数是待截取的字符串的起始位置,第二个参数是待截取字符串的长度。

QString str = "Hello, World!";
QString newStr = str.mid(7, 5); // 从字符串的第7个字符开始,截取5个字符,newStr的值为"World"
也可以不指定第二个参数,则只截取起始位置之后的所有字符。

QString str = "Hello, World!";
QString newStr = str.mid(7); // 从字符串的第7个字符开始,截取之后的所有字符,newStr的值为"World!"

使用left和right方法可以从字符串的左侧或右侧分别截取指定长度的字符串。left方法从左侧开始截取,接收一个参数指定要截取的字符长度。right方法从右侧开始截取,同样接收一个参数指定要截取的字符长度。

QString str = "Hello, World!";
QString newStr1 = str.left(5); // 从字符串的左侧开始,截取5个字符,newStr1的值为"Hello"
QString newStr2 = str.right(6); // 从字符串的右侧开始,截取6个字符,newStr2的值为"World!"

(2)QString字符串替换
QString中提供了replace方法用于字符串替换。replace方法接收两个参数,第一个参数是被替换的字符串,第二个参数是替换后的字符串。

QString str = "Hello, World!";
str.replace("World", "Mars"); //将"World"替换成"Mars",str的值变为"Hello, Mars!"
如果需要在替换前先判断一下字符串中是否包含指定的子串,可以使用contains方法。

QString str = "Hello, World!";
if (str.contains("World")) 
{
    str.replace("World", "Mars");
}

(3)QString分隔符取数据
QString提供了split方法用于根据指定分隔符对字符串进行分割。split方法接收一个参数,即指定的分隔符,返回一个字符串列表,表示分割后得到的所有子串。

QString str = "apple,banana,pear";
QStringList list=str.split(","); //按","为分隔符分割字符串,list的值为["apple", "banana", "pear"]
split方法还可以接收第二个参数,表示分割后的子串的最大数量。

QString str = "apple,banana,pear";
QStringList list = str.split(",", 2); // 按","为分隔符分割字符串,返回2个子串,list的值为["apple", "banana,pear"]

(4)QString如何截取字符串
除了之前介绍的mid、left和right方法之外,QString还提供了几种截取字符串的方法。
一种是使用remove方法,先删除指定位置及之后的字符,再删除指定位置及之前的字符,即可得到所需的子串。

QString str = "Hello, World!";
str.remove(str.indexOf(','), str.length()); // 删除","及其后的字符
str.remove(0, str.lastIndexOf(' ') + 1); // 删除第一个空格及其前面的字符

另一种是使用section方法,可以方便地从复杂字符串中提取子串。section方法接收三个参数,第一个参数是指定的分隔符,第二个参数是子串的索引(从0开始),第三个参数是标志位,表示截取的方式。

QString str = "China,Beijing,Chaoyang";
QString city = str.section(',', 1, 1); // 返回第2个子串"Beijing"

标志位有三个选项:
QString::SectionDefault:默认选项,截取指定索引对应的子串。 QString::SectionSkipEmpty:如果截取得到的子串为空,则跳过。 QString::SectionIncludeLeadingSep:将分隔符放在截取得到的子串前面。

(5)QString查找字符串
在QString中,可以使用indexOf和lastIndexOf方法查找指定字符串的位置。这两个方法都接收两个参数,第一个参数是待查找的字符串,第二个参数是查找起点的位置。

QString str = "Hello, World!";
int pos1 = str.indexOf("l"); // 查找"l"第一次出现的位置,pos1的值为2
int pos2 = str.lastIndexOf("l"); // 查找"l"最后一次出现的位置,pos2的值为10
int pos3 = str.indexOf("l", pos2 + 1); // 从pos2+1的位置开始查找"l",pos3的值为3
另外,还可以使用count方法查找指定子字符串在当前字符串中出现的次数。

QString str = "Hello, World!";
int count = str.count("l"); // 返回"l"在字符串中出现的次数,count的值为3

(6)字符串如何转成QString
在Qt中经常需要将char*、std::string等其他类型的字符串转换成QString类型,QString提供了fromStdString、fromLocal8Bit和fromUtf8等方法来实现。

char* cstr = "Hello, World!";
QString str1 = QString::fromLocal8Bit(cstr); // 将本地编码的字符串转换成QString
std::string stdstr = "Hello, World!";
QString str2 = QString::fromStdString(stdstr); // 将std::string类型的字符串转换成QString
const char* utf8str = "你好,世界!";
QString str3 = QString::fromUtf8(utf8str); // 将UTF-8编码的字符串转换成QString

(7)QString字符串分割
在使用string类型的字符串时,可以先将其转换成QString类型,然后使用split方法进行分割。另外,也可以使用stringstream对象进行分割。

using namespace std;
string str = "apple,banana,pear";
QString qstr = QString::fromStdString(str);

QStringList list = qstr.split(",");  // 使用split方法进行分割
for (int i = 0; i < list.size(); i++) 
{
    string s = list[i].toStdString(); // 将QString转换成string类型
    cout << s << endl;
}

// 使用stringstream对象进行分割
stringstream ss(str);
string s;
while (getline(ss, s, ',')) 
{
    cout << s << endl;
}

2, QStringList

QStringList继承自QList<QString>,提供字符串列表,QList的所有功能也适用于QStringList。例如
可以使用 isEmpty() 测试列表是否为空,并且可以调用诸如append(),prepend(),insert(),replace(),removeAll(),removeAt(),removeFirst(),removeLast()和removeOne()之类的函数来修QStringList。QStringList提供了一些便利功能,这些功能使处理字符串列表更加容易:通过insert() append()或者重载的operator+=() 和 operator «()将字符串添加到列表中

QStringList fonts = { "Arial", "Helvetica", "Times" };
fonts << "Courier" << "Verdana";
fonts += "chinese";
for (int i = 0; i < fonts.size(); ++i)
{
    qDebug()<< fonts.at(i).toLocal8Bit().constData();
}
QStringListIterator javaStyleIterator(fonts);
while (javaStyleIterator.hasNext())
{
    qDebug() << javaStyleIterator.next().toLocal8Bit().constData();
}
QStringList::const_iterator constIterator;
for(constIterator=fonts.constBegin(); constIterator!=fonts.constEnd();,++constIterator)
{
    qDebug() << (*constIterator).toLocal8Bit().constData();
}

3,QByteArray

QByteArray用于存储原始字节(包括’0’和传统的以’0’结尾的 8 位字符串)。使用QByteArray比使用const char*更为方便。QByteArray在主要以下两种情况中使用:需要存储原始二进制数据时和在内存保护至关重要。QByteArray可以包含“0”, rize()函数总会计算”0”,但是date()和constData()返回结果总是以”0”作为结束标志:

qDebug()<<byte.right(2);
qDebug()<<byte.left(2);
qDebug()<<byte.mid(2,2);
QByteArray byte1("ca\0r\0t");
qDebug()<<byte1.size(); // Returns 2.
qDebug()<<byte1.data();
qDebug()<<byte1.constData(); // Returns "ca" with␣

QByteArray byte2("ca\0r\0t", 3);
qDebug()<<byte2.size(); // Returns 3.
qDebug()<<byte2.constData(); // Returns "ca\0" with,→terminating \0.
QByteArray byte3("ca\0r\0t", 4);
qDebug()<<byte3.size(); // Returns 4.
qDebug()<<byte3.constData(); // Returns "ca\0r" with␣terminating \0.
for(int i=0; i<byte3.size();i++)
{
    qDebug()<<byte3.at(i);
}
const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};
QByteArray byte4(QByteArray::fromRawData(cart, 6));
qDebug()<<byte4.size(); // Returns 6.
qDebug()<<byte4.constData(); // Returns "ca\0r\0t" without␣terminating \0.

resize()可以重新设置数组的大小,并按字节数重新初始化数据字节。QByteArray使用基于0的
索引,就像C++数组一样,可以使用operator[]访问特定索引位置的字节,如果只读,我们也可以使用at()访问指定的字节,left()、right()或 mid()则可以一次读取多个字节:

byte.resize(5);
byte[0] = 0x3c;
byte[1] = 0xb8;
byte[2] = 0x64;
byte[3] = 0x18;
byte[4] = 0xca;
qDebug()<<byte;
qDebug()<<byte[3];
qDebug()<<byte[4];
for (int i = 0; i < byte.size();i++) 
{
    qDebug()<<byte.at(i);
}
qDebug()<<byte.right(2);
qDebug()<<byte.left(2);
qDebug()<<byte.mid(2,2);

QByteArray提供用于修改字节数据的基本功能:追加append(),前置添加prepend(),插入
insert(),替代replace()和移除remove()。indexOf()或lastIndexOf()提供查找QByteArray中所有出现的特定字符或子字符串,返回字符或子字符串的索引位置(如果找到的话)。contains()用于检查 QByteArray是否包含特定字符或子字符串,count()则可以用来统计特定字符或子字符串在字节数组中出现的次数。

QByteArray byte5("and");
qDebug()<<byte5;
byte5.prepend("rock ");
qDebug()<<byte5;
byte5.append(" roll");
qDebug()<<byte5;
byte5.replace(5, 3, "&");
qDebug()<<byte5;



QByteArray byte6("We must be <b>bold</b>, very <b>bold</b>");
int j = 0;
while ((j = byte6.indexOf("<b>", j)) != -1) 
{
    qDebug() << "Found <b> tag at index position " << j;
    ++j;
}
if(byte6.contains("b"))
{
    qDebug()<<byte6.count("b");
}

4, QBitArray

QBitArray是一个数组,访问单个位并提供在整个位数组上工作的运算符(AND,OR,XOR和NOT)。

使用testBit()和setBit()访QBitArray中的位比使用operator[]效率更高:

bit.setBit(0, false);
bit.setBit(1, true);
bit.setBit(2, false);
qDebug()<<bit;

QBitArray区分数组null和empty;分别通过isNull()和isEmpty()来判断
isNull()如果此位数组为null,则返回true;否则返回false;
isEmpty()此位数组的大小是否为0,是返回true;否则返回false

qDebug()<<QBitArray().isNull();
qDebug()<<QBitArray().isEmpty();
qDebug()<<QBitArray(3).isNull();
qDebug()<<QBitArray(3).isEmpty();

QBitArray支持位运算

QBitArray bit_x(5);
bit_x.setBit(3, true);// x: [ 0, 0, 0, 1, 0 ]
QBitArray bit_y(5);
bit_y.setBit(4, true);// y: [ 0, 0, 0, 0, 1 ]
bit_x |= bit_y;// x: [ 0, 0, 0, 1, 1 ]
qDebug()<<bit_x<<bit_y;
bit_x &= bit_y;// x: [ 0, 0, 0, 0, 1 ]
qDebug()<<bit_x<<bit_y;

二,连续容器和关联容器

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

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

添加元素办法1
	QVector<QString> strArray;
	strArray.append("AAA"); 
添加元素办法2
    QVector<QString> strArray;
    strArray<<"BBB";  //可以这样
    strArray<<"MyName"<<"is"<<"LEO";


插入
    strArray.insert(1,"YYY");
删除
 	strArray.remove(1); //删除第一个元素,从0开始
   	strArray.remove(1,3); //从1开始,删除3个元素
	strArray.pop_back();   // 删除末尾元素    
    strArray.pop_front();   // 删除开始位置元素
替换
    strArray.replace(1,"LED");
末尾追加
    append()


遍历办法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";
    }  

2,QList

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

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

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

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


删除方式1:从列表删除
QString str = List.takeAt(2); //从列表中删除第3个元素,并获取它
删除方式2:从列表删除
List.removeAt(2);//从列表中删除第3个元素
删除方式3:根据内容删除
QList<QString> list;
list << "sun" << "cloud" << "sun" << "rain";
list.removeOne("sun");


改变位置
list.swap(1,3);//交换位置1和位置3的元素
list.move(1,4);//把第一个元素移到第四个元素,其他元素顺移
修改
QList<QString> list;
list << "AAA" << "BBB" << "CCC";
list.replace(1, "DDD");//参数1 元素下标, 参数2 修改的结果值


查找方式1
int index = list.indexOf("mm");//返回该元素的下标值
查找方式2
bool isCon = list.contains("23");//列表是否有某元素 成功返回true 否则false
查找方式3
index = list.count();//列表总元素 同list.length();
index = list.count("AAA");//列表中有几个这样的元素


遍历访问方式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

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

添加方式1
QLinkedList<QString> Listl;
List << "AAA" << "BBB" << "CCC";
添加方式2
QLinkedList<QString> List;
list.append("aaa"); //链表尾部插入
list.push_back("aaa"); //链表尾部插入
list.push_front("5");//链表表头插入


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

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


遍历
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

要存储纯二进制数据(raw binary data)(原始数据)或8-bit编码文本字符串就用QByteArray

访问:QByteArray的访问方式有四种:[]、data[]和at()、constData[]。其中[]和data[]为可读可写;at()和constData[]为只读,因此访问用这两种速度较快。
QByteArray ba;
ba.resize(3);
ba[0] = 0x30;
ba[1] = 0x31;
ba[2] = 0x32;
qDebug() << ba.toHex(); //return “303132”



查找
QByteArray x("sticky question");
QByteArray y("sti");
x.indexOf(y);           //returns 0


数据转换
QByteArray ba;
int n = 63;
ba.setNum(n); // ba == “63”
ba.setNum(n, 16); // ba == “3f”


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,QSet

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

插入
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);  
}  


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

应用举例

// 创建一个字符串类型的集合(QSet)对象,名为 set
QSet<QString> set;
// 向集合中插入字符串"one" 、"three"、"seven"
set.insert("one");
set.insert("three");
set.insert("seven");
// 使用流操作符连续插入字符串"twelve"、"fifteen"、"nineteen" 到集合中
set << "twelve" << "fifteen" << "nineteen";
// 判断集合中是否包含字符串"fifteen",如果包含则输出"set contains fifteen"
if (set.contains("fifteen"))
qDebug()<<"set contains fifteen";
// 使用 foreach 循环遍历集合中的字符串,并输出其值
foreach (const QString &value, set)
qDebug() << value;

6,QStack

QStack是一种基于栈(Stack)的高级数据结构,QStack容器是一种后进先出(LIFO)的数据结构,即最后一个进入堆栈的元素将最先被移除。堆栈是后进先出(LIFO)结构,使用 push()将项目添加到堆栈的顶部,并使用pop()从顶部检索项目。在 top()函数可以访问到的最上方项目而不删除。

// 创建一个整数类型的栈(QStack)对象,名为stack
QStack<int> stack;
// 使用 push() 压入元素
stack.push(1);
stack.push(2);
stack.push(3);
// 使用 top() 查看栈顶元素
qDebug() << "Top element:" << stack.top();
// 使用 size() 查看堆栈大小
qDebug() << "Stack size:" << stack.size();
// 使用 pop() 移除并返回栈顶元素
int poppedValue = stack.pop();
qDebug() << "Popped value:" << poppedValue;
// 使用 isEmpty() 检查堆栈是否为空
qDebug() << "堆栈是否空的:" << (stack.isEmpty() ? "Yes" : "No");
// 使用 operator<< 压入元素
stack << 4 << 5;
// 当栈不为空时执行循环,输出并弹出栈顶的元素
while (!stack.isEmpty())
qDebug() << stack.pop();
qDebug() << "堆栈是否空的:" << (stack.isEmpty() ? "Yes" : "No");

7,QQueue

QQueue类是提供队列的通用容器,队列是先进先出(FIFO)结构。使用enqueue()将项目添加到队列的尾部,并使用dequeue()从项目头检索项目,head()函数提供了访问头项目而不删除数据。QQueue继承自QList,因此可以方便地利用QList的功能实现队列的基本操作。QQueue提供 enqueue(),dequeue()和 head()三个便利功能,实现fifo定义

//创建一个空的 int 型 QQueue 对象,名为 queue
QQueue<int> queue;
//入队
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
//获取队列大小
qDebug() << "队列大小:" << queue.size();
//检查队列是否为空
qDebug() << "队列是否为空:" << queue.isEmpty();
//查看队列的头部元素
qDebug() << "队列的头部元素:" << queue.head();
/出队元素
int firstElement = queue.dequeue();
qDebug() << "出队元素:" << firstElement;
//获取队列中的第一个和最后一个元素
qDebug() << "First element:" << queue.first();
qDebug() << "Last element:" << queue.last();
//检查队列是否包含特定值
qDebug() << "检查队列是否包含特定值 3:" << queue.contains(3);
//出队所有元素
while (!queue.isEmpty())
qDebug() << queue.dequeue();

8,QVariant

QVariant类是Qt的共用体union数据类型,不仅能保存很多Qt类型的值,包括QColor,QBrush,

QFont,QRect,QString及QSize等等,而且能存放Qt的容器类型值. 常用于存储不同的数据类型,可以在接口返回值中广泛使用。

定义一个int类型的QVariant
QVariant vNum(100);
qDebug() << vNum.toInt();


定义一个float类型的QVariant
QVariant vPI(3.14);
qDebug() << vPI.toFloat();


定义一个QString类型的QVariant
QVariant vStr("Hello!");
qDebug() << vStr.toString();


定义一个bool类型的QVariant
QVariant vBool(false);
qDebug() << vBool.toBool();


定义一个QColor类型的
QVariantQColor color = QColor(Qt::yellow);
QVariant vColor(color);
qDebug() << vColor.type();
qDebug() << vColor.value<QColor>();

9,QMultiMap

QMultiMap继承自QMap并对其功能进行了扩展,使其能够存储多个值,多值映射是一种允许使
用同一键的多个值的映射。

// 声明三个 QMultiMap 类型的变量,QMultiMap 是一种可以存储键值对的容器,并且可以存储重
复的键。
QMultiMap<QString, int> map1, map2, map3;
map1.insert("plenty", 100); // 在 map1 中插入键为"plenty",值为 100 的元素
map1.insert("plenty", 2000); // 在 map1 中再次插入键为"plenty",值为 2000 的元
素,这不会覆盖之前的元素,而是在相同键下插入新的元素
qDebug()<<map1.size();
map2.insert("plenty", 5000); // 在 map2 中插入键为"plenty",值为 5000 的元素。
qDebug()<<map2.size();
// 使用 QMultiMap 的 operator+ 将 map1 和 map2 合并,结果存储在 map3 中
// 如果两个 map 中存在相同的键,那么在 map3 中该键对应的值将是两个 map 中该键对应的所有
值的集合
map3 = map1 + map2;
qDebug()<<map3.size();
// 获取在 map3 中键为"plenty" 的所有值,并将这些值存储到列表中
// 然后遍历 valueslist,并输出其中的每个值
QList<int> valueslist = map3.values("plenty");
for (int i = 0; i< valueslist.size(); ++i)
qDebug() << valueslist.at(i);

10,QMap

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

插入:可以用运算符[ ]插入一对 (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);


查询:获取值
int num1 = map["thirteen"];
int num2 = map.value("thirteen");
查看QMap对象中是否包含某一项:
int timeout;
if (map.contains("TIMEOUT"))
{
	timeout = map.value("TIMEOUT");
}


遍历:查看键值
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;

11,QHash

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

插入
	QHash<int,QString> qhash;
     //方式一
     qhash[1] = "1";
     qhash[2] = "2";
     qhash[3] = "3";
 
     //方式二
     qhash.insert(4, “4”);


获取值
    //方式一   
    QString str1=qhash.value(1);//str1="1";
 
    //方式二
    QString str2=qhash[2];//str1="2";


查找
     QString str;
    if(qhash.contains(1))
    {
        str=qhash.value(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);//删除
	    }
    }


删除
    qhash.erase(it);//在迭代器中使用
    qhash.remove(key);

三,迭代器

上一篇:工厂数字化看板是什么?部署工厂数字化看板有什么作用?


下一篇:工厂能耗管控物联网解决方案