Qt容器类

Qt中的容器和STL没有多大的区别,只是方法接口上有些不同。只列举几个容器,需要的可以了解的查查文档

QStack

// 概念都是一样的
QStack<int> em;
em.push(1);	// 添加元素至栈顶
em.pop();	// 从栈中删除顶部元素并返回它
em.top();	// 仅仅返回对栈顶元素的引用
....

QQueue

QQueue<int> em1;
em1.enqueue(1);	// 添加元素到队尾
em1.head();		// 返回对队列首项的引用
em1.dequeue();	// 移除队列中的首项并返回
....

QList

QList<QString> list;
list << "aa" << "bb" << "cc";		// qt中插入元素可以采用<<
list.replace(2,"bc");		// 替换函数,将cc换为bc
list.append("dd");			// 在列表尾部添加
list.prepend("mm");			// 在列表头部添加
QString str = list.takeAt(2);	// 在列表中删除第三个项目,并获取它
list.insert(2,"mm");			// 在位置2插入项目
list.swapItemsAt(1,3);			// 交换元素1和元素3
list.contains("mm");		// 列表中是否包含"mm"
list.count("mm");			// 列表中mm的个数
list.indexOf("mm");			// 返回第一个匹配的位置
list.indexOf("mm",2);		// 也可以指定从哪个索引开始查找

索引数据同STL一样,采用[]和at()方式

QMap

QMap<QString,int> map;
map["one"] = 1;		// 插入("one",1);
map.insert("seven",7);	//采用insert函数进行插入
int value1 = map["six"];	// 获取键的值,采用[]操作符,如果map中没有该键,那么会自动插入
int value2 = map.value("five");	// 使用value()函数获取键的值,采用函数当不存在时不会自动插入
int value3 = map.value("nine",9);	// 当键不存在时,value默认返回0,这里可以设定该值,如这里设定为9
map.insert("ten",10);
map.insert("ten",100);		// map一个键对应一个值,如重新给键赋值会覆盖先前的值
// 可以使用*操作符返回一个项目,然后使用key()和value()来分别获取键和值
QMap<QString,int>::const_iterator p;
for(p = map.constBegin();p != map.constEnd()l ++p){
    qDebug() << p.key() << ":" << p.value();	
}

QMultiMap

// 可以采用QMultiMap来实现一键多值
QMultiMap<QString,int> map1,map2,map3;
map1.insert("values",1);
map1.insert("values",2);
map2.insert("values",3);
map3 = map2 + map1;			// 可以进行相加,map3的values将包含2,1,3
QList<int> myValues = map3.values("values");
for(int i = 0;i < myValues.size();++i){
    qDebug() << myValues.at(i);
}

需要注意的是,容器可以嵌套! 如QMap<QString,QList >这里的"> >“符号之间是有一个空格,不然编译器会将它当作”>>" 操作符对待。

遍历容器

Qt的容器类提供了两种类型的迭代器,Java风格迭代器和STL风格迭代器。实际当中使用STL风格迭代器更好点,因为它的效率更高,而且可以和Qt,STL的通用算法一起使用(只码STL的感兴趣的可以查查看)。
在这里插入图片描述

#include <QList>
QList<QString> list;
list << "A" << "B" << "C" << "D";
QList<QString>::iterator i;		// 读写迭代器
for(i = list.begin();i != list.end();++i){
    *i = (*i).toLower();	// 转换为小写
    qDebug() << *i;	
}
QList<QString>::const_iterator j;	// 只读迭代器
qDebug() << "the forward is:";
for(j = list.constBegin();j!= list.constEnd();++j){
    qDebug() << *j;
}

Qt容器常用的STL算法

#include <algorithm>
QStringList list;
list << "one" << "two" << "three";
QList<QString> list1(3);
std::copy(list.begin(),list.end(),list1.begin());	// 将list中元素复制到list1中
bool ret1 = std::equal(list.begin(),list.end(),list1.begin());	// 将list和list1的元素逐个比较,全部相同则返回true

QList<QString>::iterator i = std::find(list.begin(),list.end(),"two");	// 找到返回对应值的迭代器,否则返回end()

std::fill(list.begin(),list.end(),"eleven");	// 将list中的所有所有项目填充为eleven

QList<int> list2;
list2 << 3 << 3 << 6 << 6 << 6 << 8;
int countsum = std::count(list2.begin(),list2.end(),6);	// 查找6的个数

std::sort(list2.begin(),list2.end());	// 使用快速排序算法对list2进行升序排序

std::reverse(list2.begin(),list2.end());	// 反转容器内指定范围的所有元素

std::stable_sort(list2.begin(),list2.end());	// 使用稳定排序算法对list2进行升序排序,如排序前在前的元素,有相同的元素时,在前的元素还是在前,如12,12

QString

#include <QStringList>
QString str = "hello";
str[0] = QChar('H');	// 将第一个字符换为H
str.append(" Qt");		// 向字符串后添加Qt
str.replace(1,4,"i");	// 将第1个字符开始的后面4个字符替换为字符串"i"
str.insert(2,"my");		// 在第2个字符后插入" my"
str = str + "!!!";		// 两个字符串结合
str1 = " hi\r\n Qt! \n ";
QString str2 = str1.trimmed();	// 除去字符串两端的空白字符
str2 = str1.simplified();	// 出去字符串两端和中间多余的空白字符

str = "hi,my,,Qt";
QStringList list = str.split(",",Qt::SkipEmptyParts);	//从字符串中有,的地方将其分为多个子字符串
str = list.joni(" ");	// 将各个子字符串组合为一个字符串,中间用" "隔开

QString().isNull();		// true
QString().isEmpty();	// true
QString("").isNull();	// false
QString("").isEmpty();	// true
// QString中一个null字符串和一个空字符串并不是完全一样的,一个null字符串是使用QString的默认构造函数或者在构造函数中传递了0来初始化的字符串,一个空字符串是指大小为0的字符串。一般null字符串都是空字符串,但一个空字符串不一定是一个null字符串,一般使用isEmpty()来判断一个字符串是否为空。


// 查询
str = "yafeilinux";
str.right(5);	// 右侧5个字符
str.left(5);	// 左侧5个字符
str.mid(2,3);	// 包含第2个字符以后3个字符的子字符串
str.indexOf("fei");		// 结果为2
str.at(0);		// 结果为y
str.count('i');	// 结果为2
str.startsWith("ya");		// 判断str是否以ya开始
str.endsWith("linux");		// 判断str是否以linux结尾
str.contains("lin");		// str是否包含lin字符串
QString temp = "hello";
if(temp > str)
    qDebug() << temp;
else
    qDebug() << str;	// 结果为输出str


// 转换
str = "100";
str.toInt();	// 转换为100
int num = 45;
QString::number(num);	// 结果为"45"
str = "123.456";
str.toFloat();		// 结果为123.456
str = "abc";
str.toUpper();		// 结果为ABC
str = "ABC";
str.toLower();		// 结果为abc

int age = 25;
QString name = "yafei";
str = QString("name is %1,age is %2").arg(name).arg(age);	// name代替%1,age代替%2

str = " % 1 % 2";
str.arg("% 1f","hello");	// 结果为% 1f hello
str.arg("% 1f").arg("hello");	// 结果为hellof % 2

隐式共享

隐式共享称为写时复制。使用隐式共享类的对象作为参数传递是既安全又有效的,只有一个指向该数据的指针被传递了,只有当函数向它写入时才会复制该数据。

QPixmap p1,p2;
p1.load("image.bmp");	
p2 = p1;		// p1与p2共享数据
QPainter paint;
paint.begin(&p2);	// p2被修改
paint.drawText(0,50,"Hi");
paint.end();		// 这个例子采用了引用计数,不清楚的看看共享指针原理

深复制和浅复制。深复制意味着复制一个对象,而浅复制则是复制一个引用(仅仅只是一个指向共享数据块的指针)。深复制非常耗能,需要消耗很多内存和CPU资源;而浅复制则非常快速,因为它只需要设置一个指针和增加引用计数的值。当隐式共享类使用"=“操作符时就使用浅复制,如"p2 = p1”,但是当对象被修改时,才必须进行深复制(这也是指针灵活的地方)。

共享的好处是程序不需要进行不必要的数据复制,从而减少数据的复制和使用更少的内存,对象也可以很容易地被分配,或者作为参数被传递,或者从函数被返回。隐式共享在后台进行,实际编程不必关注。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值