QT数据类型和容器用法

news2024/10/11 12:21:48

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);

三,迭代器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1553940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ基础笔记

视频链接&#xff1a;【黑马程序员RabbitMQ入门到实战教程】 文章目录 1.初识MQ1.1.同步调用1.2.异步调用1.3.技术选型 2.RabbitMQ2.1.安装2.1.1 Docker2.1.1 Linux2.1.1 Windows 2.2.收发消息2.2.1.交换机2.2.2.队列2.2.3.绑定关系2.2.4.发送消息 2.3.数据隔离2.3.1.用户管理2…

Elasticsearch:语义搜索即服务处于卓越搜索的中心

作者&#xff1a;来自 Elastic Sherry Ger, Stephen Brown 对于许多企业来说&#xff0c;搜索卓越中心&#xff08;center of excellence - COE&#xff09;向其用户提供搜索服务&#xff0c;从不同的数据源中整理知识&#xff0c;并将搜索功能集成到其内部和外部应用程序中。…

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023 年第 13 号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中&#xff0c;首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

如何配置本地ssh连接远程Linux服务器

1.条件 本地操作系统Ubuntu远程服务器&#xff08;Linux都可以&#xff09; 本地如果是Window,其实也一样&#xff0c;但是需要先下载ssh和putty工具&#xff0c;然后操作步骤是一样的 2.生成ssh公私钥对 # 在本地重新生成SSH公私钥对非常简单&#xff0c;在你的命令行终端&a…

词令关键词口令直达工具:打开「词令」输入关键词直达口令怎么使用?

词令是一款关键词口令直达工具&#xff1b;使用词令关键词口令直达工具&#xff0c;输入指定的词令关键词直达口令&#xff0c;搜索直达该词令关联的网站、页面、程序、应用、服务或功能等等&#xff0c;实现一键直达目标&#xff0c;避免繁琐的查找点击行为&#xff0c;提高用…

报错 /core/library/think/cache/driver/File.php 第 126 行左右(已解决)

报错 /core/library/think/cache/driver/File.php 第 126 行左右 解决方法&#xff1a; 网站后台版本低于v1.5.2出现的缓存问题&#xff0c;如果无法登录后台了&#xff0c;就通过FTP&#xff0c;把 /data/runtime 里的都删掉&#xff0c;然后进后台升级到最新版 一、进入宝…

初步了解JavaSE

目录 前言&#xff1a; 一、Java SE主要包含模块&#xff1a; 二、JavaSE的环境搭建 三、JavaSE简单入门 1&#xff09;文件名称不对&#xff0c;如果有一个叫 helloworld.java&#xff0c;但是class命名为HelloWord. 2&#xff09;如果希望我们文件名称和类名不一致&…

光耦合器电路基本概述

在当今快速发展的技术环境中&#xff0c;光耦合器电路在确保电信号跨隔离电路的无缝传输方面发挥着关键作用。这些半导体器件通常被称为光电隔离器&#xff0c;具有许多优点&#xff0c;包括电路隔离、信号传输和精确的电路控制。然而&#xff0c;如果不全面了解市场上各种光耦…

【漏洞复现】通天星CMSV6 admin 弱口令漏洞(CVE-2024-29666)

0x01 产品简介 CMSV6平台是基于车辆位置信息服务和实时视频传输服务的创新技术和开放运营理念。为GPS运营商车辆硬件设备制造商、车队管理企业等车辆运营相关企业提供核心基础数据服务。 0x02 漏洞概述 CMSV6 7.31.0.2、7.32.0.3版本中存在弱密码漏洞&#xff0c;未授权的攻…

俄罗斯深陷芯片自主困境,良率仅5成 |百能云芯

俄罗斯的芯片产业一直以来都面临着诸多挑战&#xff0c;尤其是在当前的国际形势下&#xff0c;这些挑战更加凸显。随着俄乌冲突的爆发&#xff0c;西方国家对俄罗斯实施了一系列经济制裁&#xff0c;导致俄罗斯科技产业受到了严重影响。据了解&#xff0c;俄国最大的本土芯片厂…

GooglePlay无法下载应用问题

问题如下 解决方法 1、实际上是因为google尚未添加apk downloader扩展程序 2、添加该扩展程序后&#xff0c;在应用中搜索应用名即可 欧克&#xff01;下载完成

KSD测试系统使用方法和注意事项

①下载链接在最顶部&#xff1b; ②安装方法&#xff1a;应该先将测试设备绑定在假人身上&#xff0c;测试设备不能过度往下拉&#xff0c;传感器绑在脖子上&#xff0c;切记最后才开传感器开关&#xff01;&#xff01;&#xff01;开传感器后3秒内不要碰测试设备衣服&#x…

2024年电商圈大地震!腾讯带着视频号小店,杀进电商市场了!

大家好&#xff0c;我是电商糖果 今年的电商圈真的是热闹非凡&#xff0c;各个平台之间硝烟四起。 当几大平台打的火热的时候&#xff0c;腾讯却偷偷的推出了视频号小店&#xff0c;想要加入混战&#xff0c;吃到电商这盘大蛋糕。 可能大部分人都不知道什么是视频号小店&…

C++从入门到精通——函数重载

函数重载 前言一、函数重载概念二、函数重载的分类参数类型不同的函数重载参数个数不同的函数重载参数类型顺序不同的函数重载 三、函数重载的具体代码展示main.cpp 四、为什么为什么C支持函数重载&#xff0c;而C语言不支持函数重载呢 前言 函数重载是指在同一个作用域内&…

芯片测试介绍

一、芯片测试的目的 芯片测试的目的就两个&#xff1a; 1、确认芯片与产品手册上写的内容一致&#xff0c;就是看做出来的芯片跟设计的是不是一致的&#xff1b; 2、把芯片的边界条件测出来&#xff0c;就是看芯片有多耐操。 二、芯片测试分类 大家听到最多的测试可能就是…

数据结构课设-基于Python的校园导航系统(附源码)

一月份的数据结构课设完成后&#xff0c;我对Python的了解也更加深刻。现将课设报告及源码开源&#xff0c;不足之处希望大家指正。源码我放在博客主页的资源中&#xff0c;需要的话大家自行下载&#xff08;用户信息保存在 users.json 文件中&#xff0c;地图信息保存在 campu…

如何缩短职场人与人之间的差距?答案或许就隐藏在一纸社科院与杜兰大学能源管理硕士学位之中

你是否曾惊叹于同事某某的飞速进步&#xff0c;短短两年内连升三级&#xff0c;如同职场上的彗星划破夜空&#xff1f;每当看到他们晋升的喜讯在群里传播&#xff0c;你的内心是否也曾涌起一股难以名状的涟漪&#xff1f;与你一同踏入公司的伙伴&#xff0c;如今已是经理级别&a…

微服务demo(二)nacos服务注册与集中配置

环境&#xff1a;nacos1.3.0 一、服务注册 1、pom&#xff1a; 移步spring官网https://spring.io&#xff0c;查看集成Nacos所需依赖 找到对应版本点击进入查看集成说明 然后再里面找到集成配置样例&#xff0c;这里只截一张&#xff0c;其他集成内容继续向下找 我的&#x…

没学数模电可以玩单片机吗?

我们首先来看一下数电模电在单片机中的应用。数电知识在单片机中主要解决各种数字信号的处理、运算&#xff0c;如数制转换、数据运算等。模电知识在单片机中主要解决各种模拟信号的处理问题&#xff0c;如采集光照强度、声音的分贝、温度等模拟信号。而数电、模电的相互转换就…

2024年 前端JavaScript 进阶 第1天 笔记

1.1-作用域和作用域链 1.2-JS垃圾回收机制以及算法 1.3-JS闭包 JS进阶-day1-154-JS闭包_哔哩哔哩_bilibili 1.4-变量和函数提升 1.5-函数剩余参数和展开运算符 运用场景&#xff1a; 1.6-ES6箭头函数的使用 1.7-数组解构 1.8-对象解构 最简写法&#xff1a; 1.9-forEach遍历数…