【QT】容器类的迭代

    迭代器(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关键字遍历一个容器变量是创建了容器的一个副本,所以不能修改原来容器变量的数据项。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Self-supervised Graph Learning for Recommendation 详解

目录 摘要 引言 预备知识 方法 3.1 图结构数据增强 3.2 对比学习 3.3 多任务学习 3.4 理论分析 摘要 基于用户-物品图的推荐表示学习已经从使用单一 ID 或交互历史发展到利用高阶邻居。这导致了图卷积网络(GCNs)在推荐方面的成功&#xff0c;如 PinSage 和 LightGCN。尽管具…

[Firefly-Linux] RK3568 pca9555芯片驱动详解

文章目录 一、PAC9555 介绍二、ITX-3568JQ PAC9555 使用2.1 原理图2.2 设备树三、RK3568 I2C 介绍四、PAC9555 驱动4.1 介绍4.2 数据结构4.3 驱动分析一、PAC9555 介绍 PAC9555 是一种高性能、低功耗 I/O 扩展芯片,能够提供 16 个 GPIO 通道,每个通道可以单独配置为输入或输…

C语言再学习 -- 单精度(float)和双精度(double)浮点数 与 十六进制(HEX) 之间转换(转载))

之前讲过浮点数部分&#xff0c;参看&#xff1a;C语言再学习 – 浮点数 现在程序中要将浮点数&#xff0c;通过TCP发送。那得先将其转换为十六进制才行呀。 那么问题就来了。 参看&#xff1a;C语言&#xff1a;单精度(float)和双精度(double)浮点数 与 十六进制(HEX) 之间…

完数的C语言实现xdoj30

时间限制: 2 S 内存限制: 10000 Kb 问题描述: 请写一个程序&#xff0c;给出指定整数范围[a&#xff0c;b]内的所有完数&#xff0c;0 < a < b < 10000。 一个数如果恰好等于除它本身外的所有因子之和&#xff0c;这个数就称为"完数"。 例如6是…

git 关于分支、merge、commit提交

最近开始用git终端提交代码&#xff0c;梳理了一些知识点 一 关于分支 关于分支&#xff0c;git的分支分为本地分支远程分支两种分支&#xff0c;在上传代码时&#xff0c;我们要确保当前本地分支连接了一个远程分支。 我们可以通过下面代码查看当前的本地分支&#xff1a; g…

mybatis的分页插件

在mybatis核心配置文件中&#xff1a; 这时已经用了SSM整合&#xff0c;好多像是mapper或者数据源等都移出去了 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""…

nodejs微信小程序+python+PHP新闻发布系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

这些Java并发容器,你都了解吗?

文章目录 前言并发容器1.ConcurrentHashMap 并发版 HashMap示例 2.CopyOnWriteArrayList 并发版 ArrayList示例 3.CopyOnWriteArraySet 并发 Set示例 4.ConcurrentLinkedQueue 并发队列 (基于链表)示例 5.ConcurrentLinkedDeque 并发队列 (基于双向链表)示例 6.ConcurrentSkipL…

【LLM_05】使用fastgpt搭建本地离线大语言模型(Chatglm3)问答+知识库平台

1、FastGPT 的知识库逻辑1.1 基础概念1.2 FastGPT知识库的导入1.3 FastGPT新建应用&#xff08;1&#xff09;创建一个知识库助手&#xff08;2&#xff09;创建一个python开发小助手 2、词向量比较测试2.1 开启词向量模型2.2 词向量模型性能比较 3、配置好之后的运行3.1 运行大…

Redis ziplist源码解析

area |<---- ziplist header ---->|<----------- entries ------------->|<-end->|size 4 bytes 4 bytes 2 bytes ? ? ? ? 1 byte--------------------------------------------------------------- comp…

多人聊天UDP

服务端 package 多人聊天;import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;…

第十六届山东省职业院校技能大赛中职组网络安全赛项竞赛正式试题

第十六届山东省职业院校技能大赛中职组网络安全"赛项竞赛试题 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛阶段 竞赛阶段任务阶段竞赛任务竞赛时间分值A、B模块A-1登录安全加固180分钟200分A-2本地安全策略设置A-3流量完整性保护A-4事件监控A-5服务加固A-6防火墙策…

Error: Could not create the Java Virtual Machine(Linux启动tomcat成功后找不到进程8080端口)

文章目录 问题解决问题过程Tomcat版本要求 问题解决 版本冲突&#xff0c;我的jdk是1.8.x&#xff0c; tomcat 是 10.1.x的&#xff0c;要求jdk是11。 问题过程 运行 ./startup.sh 显示如下&#xff1a; 还以为运行成功呢&#xff0c; 使用命令一查&#xff0c;根本查不到进…

C语言进阶之路之内存镜像与字符操作函数篇

目录 一、学习目标&#xff1a; 二、内存镜像 什么是进程 C进程内存布局 栈内存 静态数据 数据段&#xff08;存储静态数据&#xff09;与代码段 堆内存 三、字符操作函数 函数strstr 函数strlen strlen与sizeof的区别 函数strtok 函数strcat与strncat 函数strc…

记录 | python向上取整和向下取整

python 向上取整和向下取整 向上取整 使用 ceil()&#xff1a; import mathx 0.55 x0 math.ceil(x)向下取整 使用 floor()&#xff1a; import mathx 0.55 x1 math.floor(x)如下&#xff1a;

群聊Java

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

VR远程带看,助力线下门店线上化转型“自救”

VR远程带看&#xff0c;因自身高效的沉浸式在线沟通功能&#xff0c;逐渐走进了大众的视野。身临其境的线上漫游体验以及实时同屏互联的新型交互模式&#xff0c;提升了商家同用户之间的沟通效率&#xff0c;进一步实现了远程线上一对一、一对多的同屏带看&#xff0c;用户足不…

封装校验-----Vue3+ts项目

登录校验页面 <script setup lang"ts"> import { ref } from vue import { mobileRules, passwordRules } from /utils/rules const mobile ref() const password ref() </script><!-- 表单 --><van-form autocomplete"off">&l…

使用Draw.io制作泳道图

使用Draw.io制作泳道图 一、横向泳道图1. 有标题泳道图2. 无标题泳道图3. 横纵向扩展泳道 二、纵向泳道图三、横纵交错地泳道图想做这样的图具体步骤1. 拖拽一个带标题的横向泳道图2. 拖拽一个带标题的单一图&#xff0c;并且把它放进Lane1中3. 其他注意 四、下载文件说明 一、…

CSS的逻辑组合伪类

CSS 的逻辑组合伪类有 4 种&#xff0c;分别是&#xff1a;:not()、:is()、:where()和&#xff1a;has()。 否定伪类:not() :not 伪类选择器用来匹配不符合一组选择器的元素。由于它的作用是防止特定的元素被选中&#xff0c;它也被称为反选伪类&#xff08;negation pseudo-…