Qt笔记之容器操作

2017/06/11 Qt学习

作者:鹅卵石
时间:2017年6月11日10:07:17
版本:V 0.0.0
邮箱:kevinlq@yeah.net

Qt笔记之容器操作

整理下之前在使用容器时遇到的一些问题,以及注意事项

容器分类

Qt中的容器和标准的STL容器类似,具体在使用过程中有一些区别

Qt提供的容器更轻量、更安全、更容易使用,而且提供了隐式数据共享、不可变的特性,为速度做了优化,局域较低的内存占用量,最重要的一点是它是线程安全的。这些容器类时平台无关的,不会因编译器不同而具有不同的实现。

隐式数据共享,也叫做”写时复制(copy on write)“,在我们使用容器传递参数时妈不会出现额外的性能损失

  1. QList(QLinkedList)
  2. QVector
  3. QMap
  4. QHash
  5. QStack
  6. QQueue
  7. ……
  • **QList** 是基于数组实现的列表,提供了快速的向前添加和向后追加的操作,中间插入数据性能没有QLinkedList好;
  • **QLinkedList** 是基于链表实现的,在中间插入大量的数据时性能要优于QList;
  • Qvector 用于在内存的连续存储区区域存放给定类型的值,在头部或者中间插入数据可能会很慢,因为这回引起大量数据在内存中移动;
  • QMap<key,T> 提供了字典结构类型,通常每个键与一个值关联,一般以键的顺序进行存储,如果顺序无关,QHash提供了更好的性能;
  • QMultiMap<key,T> 是QMp子类,提供了多值映射,一个键可以与多个值进行关联;
  • **QStack** 是QVector的子类,提供了后进先出( **LIFO** );
  • **QQueue** 是QList的子类,提供了先进先出( **FIFO** );
  • QHash<key,T> 和QMap具有类似的接口,但是提供了更快的查找,QHash以字母顺序存储数据;
  • QMultiHash<key,T> 这是QHash子类,提供了多值散列;

容器迭代

Java风格

java风格迭代器是在Qt4首先引入的,属于Qt应用程序推荐使用的形式;使用起来方便,但是没有STL方式高效

java风格迭代器

java 风格迭代器指向的是两个元素之间的位置,而不是元素本身,因此,可能会指向第一个元素之前的位置,也可能指向集合的最后元素之后的位置;

每一种容器都有两种Java风格的迭代器:只读访问和读写访问

容器 只读遍历 读写遍历
QList < T >
QQueue< T >
QListIterator< T > QMutableListIterator< T >
QLinkedList< T > QLinkedListIterator< T > QMutableLinkedListIterator< T >
QVector< T >
QStack< T >
QVectorIterator< T > QMutableVectorIterator < T >
QSet < T > WSetIterator< T > QMutableSetIterator< T >
QMap <key, T >
QMultiMap <key, T >
QMapIterator < T > QMutableMapIterator < T >
QHash < key,T >
QMultiHash < key,T >
QHashIterator < T > QMutableHashIterator < T >

QList简单使用

 QList<fileRecord> m_recordList;
     bool status = false;
    //加载数据
    for (int i = 0;i < 10;i++)
    {
        FileRecord record;
        record.bChecked = status;
        record.strFilePath = QString("E:/Qt/file/pic/image_%1.png").arg(i);
        record.strFileSize = QString("%1KB").arg (i*10);
        record.strSpeed = QString("%1KB/s").arg (i);
        m_recordList.append (record);
    }
    QListIterator<fileRecord> i(m_recordList);
    while (i.hasNext ()){
        qDebug ()<<i.next ().strFilePath;
    }

需要修改元素时,使用QMutableListIterator

    QMutableListIterator<fileRecord> iter(m_recordList);
    while(iter.hasNext ())
    {
        if (iter.next ().bChecked){
            iter.remove ();
        }
    }

当时在对list操作时,没有注意到只读,对容器进行动态删除后发现删不干净。原因是删除某个元素后,list的索引发生的变化

STL风格

STL风格的迭代器从Qt2.0就开始提供,并对速度进行了优化.STL风格迭代器直接指向元素本身

STL风格迭代器

有两种STL风格的容器遍历器,一种是只读,一种是读写访问。推荐使用只读访问,因为速度比读写访问要快

容器 只读遍历 读写遍历
QList < T >
QQueue < T >
QList < T >::const_iterator QList < T >::iterator
QLinkedList < T > QLinkedList < T >::const_iterator QLinkedList < T >::iterator
QVector < T >
QStack < T >
QVector < T >::const_iterator QVector < T >::iterator
QSet < T > QSet < T >::const_iterator QSet < T >::iterator
QMap <key, T >
QMultiMap <key, T >
QMap <key, T >::const_iterator QMap <key, T >::iterator
QHash <key, T >
QMultiHash <key, T >
QHash <key, T >::const_iterator QHash <key, T >::iterator

Qlist相关代码

    QList<fileRecord>::iterator i;
    for (i = m_recordList.begin ();i != m_recordList.end ();++i){
        //*i = (*i).strFilePath;
        qDebug ()<<(*i).strFilePath;
    }

debug

“E:/Qt/file/pic/image_0.png” “E:/Qt/file/pic/image_1.png” “E:/Qt/file/pic/image_2.png” “E:/Qt/file/pic/image_3.png” “E:/Qt/file/pic/image_4.png” “E:/Qt/file/pic/image_5.png” “E:/Qt/file/pic/image_6.png” “E:/Qt/file/pic/image_7.png” “E:/Qt/file/pic/image_8.png” “E:/Qt/file/pic/image_9.png”

因为list中存储的是一个结构体类型,所以这里只打印出了其中一个成员变量的值

foreach关键字

一般开发中,当仅仅只是遍历一下容器内的元素,可以使用Qt的关键字foreach,比如

    foreach (fileRecord cord, m_recordList) {
        if (!cord.bChecked){
            ui->checkBox->setChecked (false);
            return;
        }
        ui->checkBox->setChecked (true);
    }

代码中的结构体

typedef struct FileRecord{
    bool bChecked;          //是否选中
    QString strFilePath;    //文件路径
    QString strFileSize;    //文件大小
    QString strSpeed;       //传输速度
} fileRecord;

注意点

  • 对容器进行动态删除时,要考虑到删除一个元素后,容器的索引发生了变化;
  • 根据实际需求,选择合适的容器;
  • 只是读取容器元素,就不要使用读写容器方式进行遍历;

如果您对本文有任何问题,可以在下方留言,或者Email我

微信公众号:devstone,扫描二维码直接关注

Show Disqus Comments

Search

    欢迎关注我的微信号

    一个不羁的码农

    不羁的程序员

    转载请注明出处!

    Table of Contents