【QT】容器类的迭代

news2024/11/24 14:46:35
    迭代器(iterator)为访问容器类里的数据项提供了统一的方法,Qt有两种迭代器类:Java类型的迭代器和STL类型的迭代器。
    Java类型的迭代器更易于使用,且提供一些高级功能,而STL类型的迭代器效率更高。
    Qt还提供一个关键字foreach(实际是<QtGlobal>里定义的一个宏)用于方便地访问容器里所有数据项。

1.JAVA类型迭代器

1.1 JAVA类型迭代器总表

对于每个容器类,有两个Java类型迭代器:一个用于只读操作,一个用于读写操作。
Map和QHash等关联容器类的迭代器用法相同,QList和QLinkedList、QSet等容器类的用
法相同,所以下面只以QMap和QList为例介绍迭代器的用法。Java类型的迭代器如表3-3所示。
Java类型迭代器的指针不是指向一个数据项,而是在数据项之间,迭代器指针位置示意图如图所示。
图1-1  JAVA类型迭代器位置示意图

1.2 顺序容器类的迭代器的使用

1.2.1 Java类型QList容器类迭代器

(1)QListIterator常用函数
QListIterator用于移动指针和读取数据的函数见表3-4。
(2)正向遍历QList<QString>容器所有数据
    QList<QString>容器对象list作为参数传递给QListlterator<QString>迭代器i的构造函数,i
用于对list作只读遍历。起始时刻,迭代器指针在容器第一个数据项的前面(图1-1中数据项"A”
的前面),调用hasNext()判断在迭代器指针后面是否还有数据项,如果有,就调用next()跳过一个
数据项,并且next()函数返回跳过去的那个数据项。
QList<QString>list;
list<<"A"<<"B"<<"C"<<"D";
QListIterator<QString>i(list);
while(i.hasNext())
    qDebug()<<i.next();
(2)反向遍历QList<QString>容器所有数据
QListIterator<QString>i(list);
i.toBack();
while(i.hasprevious())
    qDebug()<<i.previous;
代码和正序遍历是对称的,我们调用toBack()将迭代器移到最后一项后面的位置。下图描述了在一
个迭代器上调用next()和previous()函数的效果:
(3)QMutableListIterator遍历修改容器数据
QList<int>list;
list<<1<<2<<3<<4<<5;
QMutableListIterator<int>i(list);
while(i.hasNext()){
    if(i.next()%2 != 0)
        i.remove();//remove()函数移除next()函数刚刚跳过的一个数据项,不会使迭代器失效。
    if(i.next() > 128)
        i.setValue(128);//setValue()函数可以修改刚刚跳过去的数据项的值
}

1.3 关联容器类的迭代器的使用

1.3.1 Java类型QMap容器类迭代器

        对于关联容器类QMap<KeyT>,使用QMapIterator和QMutableMapIterator迭代器类,它们具
有表3-4所示的所有函数,主要是增加了 key()和value()函数用于获取刚刚跳过的数据项的键和值。
例如,下面的代码将删除键(城市名称)里以“City”结尾的数据项。
QMap<QString,QString>map;
map.insert("Paris","France");
map.insert("New York","USA");
maP.insert("Mexico City","USA");
map·insert("Moscow","Russia");
......
QMutab1eMapIterator<QString,QString>i(map);
while(i.hasNext()){
    if(i.ne×().key().endsWith("City"))
        i.remove();
}
如果是在多值容器里遍历,可以用 findNext()或findPrevious()查找下一个或上一个值,如下面
的代码将删除上一示例代码中map里值为"USA”的所有数据项。
QMutableMapIterator<QString,QString>i(map);
while(i.findNext("USA"))
    i.remove();

2.STL类型迭代器

2.1 STL类型迭代器总表

STL迭代器与Qt和STL的原生算法兼容,并且进行了速度优化。具体类型见表3-5。
对于每一个容器类,都有两个STL类型迭代器:一个用于只读访问,一个用于读写访问。无需修改数据时一定使用只读迭代器,因为它们速度更快。
注意:在定义只读迭代器和读写迭代器时的区别,它们使用了不同的关键字,const_iterator定义只读迭代器,iterator定义读写迭代器。此外,还可以使用const_reverse_iterator和reverse_iterator定义相应的反向迭代器。
    STL类型的迭代器是数组的指针,所以“++”运算符使迭代器指向下一个数据项,“*”运算符返回数据项内容。与Java类型的迭代器不同,STL迭代器直接指向数据项,STL迭代器指向位置示意图如图2-1所示。
图2-1 STL类型迭代器位置示意图
    begin()函数使迭代器指向容器的第一个数据项,end()函数使迭代器指向一个虚拟的表示结尾的数据项,end()表示的数据项是无效的,一般用作循环结束条件。下面仍然以QList和QMap为例说明sTL迭代器的用法,其他容器类迭代器的用法类似。

2.2 顺序容器类的迭代器的使用

2.2.1 STL类型QList容器类迭代器

(1)正向只读迭代器
QList<QString>list;
list<<"A"<<"B"<<"C"<<"D";
QList<QString>::const_iterator i;
for(i = list.constBegin();i != list.constEnd();++i)
    qDebug()<<*i;
(2)反向读写迭代器
constBegin()和constEnd()是用于只读迭代器的,表示起始和结束位置。
若使用反向读写迭代器,并将上面示例代码中list的数据项都改为小写,代码如下:
QLIstanbul<QString>::reverse_iterator i;
for(i =list.rbegin();i != list.rend();++i)
    *i = i->toLower();//修改数据

2.3 关联容器类的迭代器的使用

2.3.1 STL类型QMap容器类迭代器

对于关联容器类QMap和QHash,迭代器的“*”操作符返回数据项的值。如果想返回键,使用key()函数。对应的,用value()函数返回一个项的值。
例如,下面的代码将QMap<int,int>map中所有项的键和值输出。
QMap<int,int>map;
......
QMap<int,int>::const_iterator;
for(i = list.constBegin();i != list.constEnd();++i)
    qDebug()<<i.key()<<":"<<i.value();
Qt API包含很多返回值为QList或QStringList的函数,要遍历这些返回的容器,必须先复制。由于Qt使用了隐式共享,这样的复制并无多大开销。例如下面的代码是正确的。
const QList<int>sizes = splitter->sizes();
QList<int>::const_iterator i;
for(i = sizes.begin();i !=sizes.end();++i)
    qDebug()<<*i;
提示:隐式共享(Implicit Sharing)是对象的管理方法。一个对象被隐式共享,只是传递该对象的一个指针给使用者,而不实际复制对象数据,只有在使用者修改数据时,才实质复制共享对象给使用者。如在上面的代码中,splitter->sizes()返回的是一个QList<int>列表对象sizes,但是实际上代码并不将splitter->sizes()表示的列表内容完全复制给变量sizes,只是传递给它一个指针。只有当sizes发生数据修改时,才会将共享对象的数据复制给sizes,这样避免了不必要的复制,减少了资源占用。
    下面的代码是错误的。对于STL类型的迭代器,隐式共享还涉及另外一个问题,即当有一个迭代器在操作一个容器变量时,不要去复制这个容器变量。
QList<int>::const_iterator i;
for(i =splitter->sizes().begin();i !=splitter->sizes().end();++i)
    qDebug()<<*i;

2.3.2 STL风格迭代器的API

下面的表概括了STL风格迭代器的API:
表达式
用途
*i
返回当前项
++i
将迭代器指向下一项
i += n
迭代器向前移动n项
--i
将迭代器指向上一项
i -= n
将迭代器你向后移动n项
i - j
返回迭代器i和j之间项的数目

3.foreach关键字

如果只是想遍历容器中所有的项,可以使用foreach关键字。foreach是<QtGlobal>头文件中定义的一个宏。使用foreach的句法是:
     foreach(variable,container)
使用foreach的代码比使用迭代器更简洁。例如,使用foreach遍历一的示例代码如下:
QLinkedList<QString>list;
...
QString str;
foreach(str,list)
    qDebug()<<str;
用于迭代的变量也可以在foreach语句里定义,foreach语句也可以使用花括号,可以使用break
退出迭代,示例代码如下:
QLinkedList<QString>list;
foreach(const QString &str,list)
{
    if(str.isEmpty())
        break;
    qDebug()<<str;
}
对于QMap和QHash,foreach会自动访问“键一一值”对里的值,所以无需调用values()。如果需要访问键则可以调用keys(),示例代码如下:
QMap<QString,int>map;
......
foreach(const QString &str,map.keys())
qDebug()<<str<<":"<<map.value(str);
对于多值映射,可以使用两重foreach语句,示例代码如下:
QMultiMap<QString,int>map;
...
foreach(const QString &str,map.uniqueKeys())
    foreach(int i,map.values(str))
        qDebug()<<str<<":"<<i;
注意:foreach关键字遍历一个容器变量是创建了容器的一个副本,所以不能修改原来容器变量的数据项。

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

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

相关文章

ELK(二)—Elasticsearch安装部署

一、环境准备 1.1java环境准备&#xff08;不用安装也可以&#xff0c;Elasticsearch自带了0.0,可以直接从二看了&#xff09; Elasticsearch是用Java编写的分布式搜索引擎&#xff0c;因此在安装和运行Elasticsearch时需要Java运行时环境&#xff08;Java Runtime Environmen…

如何选呼叫中心的语音通道?

如何选呼叫中心的语音通道&#xff1f; 在公网语音线路和专线语音线路中&#xff0c;选择合适的语音通道类型需要根据呼叫中心的实际需求进行综合考虑。 如果呼叫中心的预算有限&#xff0c;或者对语音质量和稳定性的要求不高&#xff0c;可以选择公网语音线路。如果需要更高…

获得矩阵对角线元素的索引 numpy.diag_indices_from()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 获得矩阵对角线元素的索引 numpy.diag_indices_from() [太阳]选择题 请问关于以下代码的选项表述错误的是&#xff1f; import numpy as np a np.array([[1, 2, 3], [4, 5, 6…

智能优化算法应用:基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.寄生捕食算法4.实验参数设定5.算法结果6.参考…

[wordpiece]论文分析:Google’s Neural Machine Translation System

文章目录 一、论文解读1.1 模型介绍1.2 模型架构1.3 wordpiece 二、整体总结 论文&#xff1a;Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation 作者&#xff1a;Yonghui Wu, Mike Schuster, Zhifeng Chen, Quoc V. Le,…

26、pytest使用allure解读

官方实例 # content of pytest_quick_start_test.py import allurepytestmark [allure.epic("My first epic"), allure.feature("Quick start feature")]allure.id(1) allure.story("Simple story") allure.title("test_allure_simple_te…

数据库学习日常案例20231203-Mysql高级 -- 日志管理篇

Mysql高级 -- 日志篇 *日志类型 1.mysql的6类日志&#xff1a; 2.日志的弊端 *慢查询日志(slow query log) *通用查询日志(general query log) 1.作用&#xff1a; 2.问题场景&#xff1a; 3.查看当前状态 &#xff1a; 4.启动日志&#xff1a; 方式1&#xff1a;永久…

MySQL 8 update语句更新数据表里边的数据

数据重新补充 这里使用alter table Bookbought.bookuser add userage INT after userphone;为用户表bookuser在userphone列后边添加一个类型为INT的新列userage。 使用alter table Bookbought.bookuser add sex varchar(6) after userage ;为用户表bookuser在userage 列后边添…

文件批量管理技巧:高效移动文件并创建文件夹,按数量分类的重要性

在日常生活和工作中&#xff0c;经常会遇到大量的文件要管理。这些文件可能存储在电脑的硬盘、外部存储设备或是云存储中。如何高效地管理这些文件&#xff0c;以便能够快速找到所需的资料&#xff0c;是一项非常重要的技能。本文讲解云炫文件管理器如何批量管理文件的技巧&…

win11 install oh-my-posh

安装配置 下载 Nerd Fonts 字体 oh-my-posh font installNerd Fonts 网站下载&#xff0c;解压后右击安装 为终端设置 Nerd Fonts 字体 修改 Windows 终端设置&#xff08;默认快捷方式&#xff1a;CTRL SHIFT ,&#xff09;&#xff0c;在settings.json文件defaults属性下添…

Python与PHP:编写大型爬虫的适用性比较

目录 一、引言 二、Python编写爬虫的优势 1、强大的数据处理能力 2、丰富的网络库和框架 3、良好的可读性和易维护性 4、社区支持和生态系统 三、PHP编写爬虫的优势 1、简单易学 2、广泛的应用领域 3、高效的性能 4、灵活的请求处理方式 四、大型爬虫的编写实例&am…

基于ssm vue技术的品牌银饰售卖平台源码和论文737

摘 要 本论文主要是针对品牌银饰售卖而开发进行概述&#xff0c;主要包括对研究的背景和研究现状&#xff0c;以及研究目的等的阐述&#xff0c;也对该系统的各种功能要求&#xff0c;对系统结构&#xff0c;数据库的设计等进行讨论。随着科技与技术的发展&#xff0c;利用计…

前端vue导出PPT幻灯片,使用pptxgen.js,超详细(赋原数据)

即上一篇文章最终代码 前端vue导出PPT&#xff0c;使用pptxgen.js 前端vue导出PPT&#xff0c;使用pptxgen.js 一个平台下有10个国家&#xff0c;这个是后端返回数据固定的&#xff0c;每一个国家下面有10个物流方式&#xff0c;这10个物流方式是这10个国家都有的&#xff0c;…

开发与AI的邂逅

目录 一、前言 二、百度文心一言 三、阿里通义灵码 3.1.工具介绍 3.2.产品功能 3.3.配置流程 3.4.适用范围 3.5.收费标准 3.6.注意事项 一、前言 前段时间&#xff0c;由OpenAI公司研发的一款聊天机器人程序ChatGPT&#xff08;全名&#xff1a;Chat Generative …

学习ShardingSphere前置知识

学习ShardingSphere前置准备知识 一. SPI SPI&#xff08;Service Provider Interface&#xff09;是一种Java的扩展机制&#xff0c;用于实现组件之间的松耦合。在SPI模型中&#xff0c;服务提供者&#xff08;Service Provider&#xff09;定义了一组接口&#xff0c;而服务…

超大规模集成电路设计----CMOS反相器(五)

本文仅供学习&#xff0c;不作任何商业用途&#xff0c;严禁转载。绝大部分资料来自----数字集成电路——电路、系统与设计(第二版)及中国科学院段成华教授PPT 超大规模集成电路设计----CMOS反相器&#xff08;五&#xff09; 5.1 静态CMOS反相器综述5.1.1 静态CMOS反相器优点…

linux的权限741

741权限 在 Linux 中&#xff0c;文件和目录的权限由三组权限来定义&#xff0c;分别是所有者&#xff08;Owner&#xff09;、所属组&#xff08;Group&#xff09;和其他用户&#xff08;Others&#xff09;。每一组权限又分为读&#xff08;Read&#xff09;、写&#xff0…

30、pytest入门内容回顾

整体结构 解读与实操 pytest30讲主要从四个方面由浅入深的进行解读&#xff0c; 开始 讲解了pytest的概述&#xff0c;安装前的准备工作&#xff08;python,pycharm,pytest&#xff09;&#xff0c;运行方式&#xff08;命令行&#xff09;&#xff0c;断言&#xff08;assert…

一起学习:大型语言模型(LLM)中的QKV(Query, Key, Value)和多头注意力机制

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

深度学习TensorFlow2基础知识学习前半部分

目录 测试TensorFlow是否支持GPU&#xff1a; 自动求导&#xff1a; 数据预处理 之 统一数组维度 定义变量和常量 训练模型的时候设备变量的设置 生成随机数据 交叉熵损失CE和均方误差函数MSE 全连接Dense层 维度变换reshape 增加或减小维度 数组合并 广播机制&#…