`
izuoyan
  • 浏览: 9224395 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Qt学习之路(37): Qt容器类之关联存储容器

阅读更多
版权声明: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://devbean.blog.51cto.com/448512/248373
今天我们来说说Qt容器类中的关联存储容器。所谓关联存储容器,就是容器中存储的一般是二元组,而不是单个的对象。二元组一般表述为<Key-Value>,也就是“键-值对”。
首先,我们看看数组的概念。数组可以看成是一种<int-Object>形式的键-值对,它的Key只能是int,而值的类型是 Object,也就是任意类型(注意,这里我们只是说数组可以是任意类型,这个Object并不必须是一个对象)。现在我们扩展数组的概念,把Key也做 成任意类型的,而不仅仅是int,这样就是一个关联容器了。如果学过数据结构,典型的关联容器就是散列(Hash Map,哈希表)。Qt提供两种关联容器类型:QMap<K, T>和QHash<K, T>。
QMap<K, T>是一种键-值对的数据结构,它实际上使用跳表skip-list实现,按照K进行升序的方式进行存储。使用QMap<K, T>的insert()函数可以向QMap<K, T>中插入数据,典型的代码如下:
QMap<QString, int > map;
map.insert("eins" , 1);
map.insert("sieben" , 7);
map.insert("dreiundzwanzig" , 23);
同样,QMap<K, T>也重载了[]运算符,你可以按照数组的复制方式进行使用:
map["eins" ] = 1;
map["sieben" ] = 7;
map["dreiundzwanzig" ] = 23;
[]操作符同样也可以像数组一样取值。但是请注意,如果在一个非const的map中,使用[]操作符取一个不存在的Key的值,则这个Key 会被自动创建,并将其关联的value赋予一个空值。如果要避免这种情况,请使用QMap<K, T>的value()函数:
int val = map.value("dreiundzwanzig" );
如果key不存在,基本类型和指针会返回0,对象类型则会调用默认构造函数,返回一个对象,与[]操作符不同的是,value()函数不会创建一个新的键-值对。如果你希望让不存在的键返回一个默认值,可以传给value()函数第二个参数:
int seconds = map.value("delay" , 30);
这行代码等价于:
int seconds = 30;
if (map.contains("delay" ))
seconds = map.value("delay" );
QMap<K, T>中的K和T可以是基本数据类型,如int,double,可以是指针,或者是拥有默认构造函数、拷贝构造函数和赋值运算符的类。并且K必须要重载<运算符,因为QMap<K, T>需要按K升序进行排序。
QMap<K, T>提供了keys()和values()函数,可以获得键的集合和值的集合。这两个集合都是使用QList作为返回值的。
Map是单值类型的,也就是说,如果一个新的值分配给一个已存在的键,则旧值会被覆盖。如果你需要让一个key可以索引多个值,可以使用QMultiMap<K, T>。这个类允许一个key索引多个value,如:
QMultiMap<int , QString> multiMap;
multiMap.insert(1, "one" );
multiMap.insert(1, "eins" );
multiMap.insert(1, "uno" );

QList<QString> vals = multiMap.values(1);
QHash<K, T>是使用散列存储的键-值对。它的接口同QMap<K, T>几乎一样,但是它们两个的实现需求不同。QHash<K, T>的查找速度比QMap<K, T>快很多,并且它的存储是不排序的。对于QHash<K, T>而言,K的类型必须重载了==操作符,并且必须被全局函数qHash()所支持,这个函数用于返回key的散列值。Qt已经为int、指针、 QChar、QString和QByteArray实现了qHash()函数。
QHash<K, T>会自动地为散列分配一个初始大小,并且在插入数据或者删除数据的时候改变散列的大小。我们可以使用reserve()函数扩大散列,使用 squeeze()函数将散列缩小到最小大小(这个最小大小实际上是能够存储这些数据的最小空间)。在使用时,我们可以使用reserve()函数将数据 项扩大到我们所期望的最大值,然后插入数据,完成之后使用squeeze()函数收缩空间。
QHash<K, T>同样也是单值类型的,但是你可以使用insertMulti()函数,或者是使用QMultiHash<K, T>类来为一个键插入多个值。另外,除了QHash<K, T>,Qt也提供了QCache<K, T>来提供缓存,QSet<K>用于仅存储key的情况。这两个类同QHash<K, T>一样具有K的类型限制。
遍历关联存储容器的最简单的办法是使用Java风格的遍历器。因为Java风格的遍历器的next()和previous()函数可以返回一个键-值对,而不仅仅是值,例如:
QMap<QString, int > map;
...
int sum = 0;
QMapIterator<QString, int > i(map);
while (i.hasNext())
sum += i.next().value();
如果我们并不需要访问键-值对,可以直接忽略next()和previous()函数的返回值,而是调用key()和value()函数即可,如:
QMapIterator<QString, int > i(map);
while (i.hasNext()) {
i.next();
if (i.value() > largestValue) {
largestKey = i.key();
largestValue = i.value();
}
}
Mutable遍历器则可以修改key对应的值:
QMutableMapIterator<QString, int > i(map);
while (i.hasNext()) {
i.next();
if (i.value() < 0.0)
i.setValue(-i.value());
}
如果是STL风格的遍历器,则可以使用它的key()和value()函数。而对于foreach循环,我们就需要分别对key和value进行循环了:
QMultiMap<QString, int > map;
...
foreach (QString key, map.keys()) {
foreach (int value, map.values(key)) {
doSomething(key, value);
}
}

本文出自 “豆子空间 ” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/248373

分享到:
评论

相关推荐

    c++容器类&QT;容器

    ### C++ 容器类与 Qt 容器详解 #### C++ 容器类概述 在C++标准库中,容器类(containers)是用于存储数据的重要组件之一,它们为程序设计提供了高度灵活且功能丰富的数据管理手段。根据数据的组织形式不同,C++中...

    QT学习之路

    14. "QT容器类之顺序存储容器、遍历器和隐式数据共享、关联存储容器" 则涵盖了Qt提供的数据结构,如QList、QMap等,它们用于存储和管理数据集合。 15. "MODEL-VIEW架构" 这是Qt中用于分离数据显示和数据管理的架构...

    Qt+学习之路+2

    ### Qt 学习之路2 知识点梳理 #### 1. 序言 - **背景**: 本文档是基于作者之前的一个系列教程——《Qt学习之路》的更新版本,旨在适应Qt的新版本和发展趋势。 - **目的**: 更新和完善原有教程内容,使其更适合Qt 4....

    其实这本PDF就是Qt学习之路第一版

    ### Qt学习之路知识点总结 #### 一、前言:Qt简介与选择 - **Qt**是一种跨平台的应用程序开发框架,广泛应用于桌面、移动设备及嵌入式系统的GUI应用程序开发。 - C++的GUI编程并非C++标准的一部分,因此开发者在...

    qt学习之路.pdf

    Qt容器类提供了丰富的数据结构支持,包括顺序存储容器、关联存储容器等。本节介绍了容器类的使用和遍历方法。 20. MODEL-VIEW架构 Qt中的MODEL-VIEW架构用于数据和视图的分离。本节讲述了如何利用这种架构创建灵活...

    Qt学习之路(1-60)

    Qt容器类提供了一套标准的C++模板容器类,用于存储数据。容器类包括顺序存储容器、关联存储容器等。学习者将学习如何在Qt中使用这些容器类,以及它们的遍历器和隐式数据共享机制。 ### Model-View架构 Model-View...

    QT之list容器

    标签“mapExamp”虽然与QT list容器无关,但提到的"map"是另一个重要的Qt容器,它是基于STL的std::map模板类。Map是一个关联容器,它按照键(key)和值(value)对的形式存储数据,且键是唯一的。在Qt中,我们可以...

    Qt容器类(QList,QMap)遍历器的使用

    通过实践和学习,你可以熟练掌握Qt容器类的使用,从而编写出更加高效和简洁的代码。 总之,Qt的QList和QMap容器类提供了强大的数据管理和遍历功能。理解并熟练运用这两种容器类的遍历器,不仅可以优化代码的执行...

    Qt学习之QListWidget添加item

    在Qt编程中,QListWidget是一个非常常用的控件,它允许我们展示一系列的项目(items)以列表形式。本篇文章将深入探讨如何在QListWidget中添加item,这对于创建用户界面,尤其是涉及到列表数据展示的应用程序至关...

    c++ qt 笔记 qt 笔记

    Qt 提供了丰富的容器类来帮助管理和操作数据。这些容器大致可以分为两大类:顺序容器和关联容器。 #### 顺序容器 - `QList`: 功能丰富,提供了下标访问。 - `QLinkedList`: 除了不提供下标访问外,其余功能与 `...

    qt5 学习资料(pdf)

    - **数据容器**:用于存储和管理数据的容器类,如 `QStringList`、`QMap` 等。 - **隐式数据共享**:Qt 中的一种优化机制,通过共享数据减少内存占用。 #### 14. 绘图系统 - **绘图基础**:Qt 提供了强大的绘图功能...

    Qt类介绍(中文版)

    **Qt类介绍(中文版)** Qt是一个跨平台的应用程序开发框架,主要应用于图形用户界面(GUI)的设计,同时也支持非GUI程序。它由Qt Company维护,并被广泛应用...学习Qt类,能帮助开发者更高效地构建跨平台的应用程序。

    Qt纸牌游戏 24点

    【Qt纸牌游戏 24点】是一款基于Qt框架开发的桌面应用,旨在帮助初学者了解和掌握Qt的基础组件和容器类的使用。Qt是一个跨平台的C++图形用户界面库,广泛应用于桌面和移动设备应用程序开发。在这个项目中,开发者运用...

    关联容器的简单应用

    在编程领域,关联容器是数据结构中的一种,它允许我们以特定的方式(通常是键值对的形式)存储元素。在这个简单的应用中,我们将关注Qt库中的两个关联容器:`QMap`和`QString`。`QMap`是一个键值对的有序集合,而`...

    QT个人学习笔记

    QT的信号与槽机制是其核心特性之一,它提供了一种安全、类型匹配的对象间通信方式,替代了传统的回调函数。在QT中,所有使用信号与槽的类必须包含`Q_OBJECT`宏,这样QT的元对象系统才能识别并处理这些信号和槽。 ...

Global site tag (gtag.js) - Google Analytics