Qt 6.5文档翻译:QMap类,QMap Class
template <typename Key, typename T> class QMap
QMap类,是一个模板类,它提供了关联数组的功能。 详细说明……
头文件: |
#include <QMap> |
CMake指令: |
find_package(Qt6 REQUIRED COMPONENTS Core) |
qmake指令: |
QT += core |
•.QMap是 隐式共享类 中的一个成员。
注意:这个类中的所有函数都是 可重入的 。
QMap<Key, T>是Qt 中的一个通用的 容器类 。它能够储存键值对((key, value) pairs),并支持通过键(key)来快速查询。
QMap和QHash的功能类似。它们的差异在于:
•.当你在QHash中遍历时,具体的条目的顺序是随机的。而在QMap中,条目一定是按照键来排序的。
•. QHash中的键的类型,必须实现operator==()方法,并且要有一个全局的qHash(Key)函数。QMap 中的键的类型,必须实现operator<()方法,以支持整体排序。从Qt 5.8.1开始,可以安全地使用指针类型作为键,即使其提供的operator<()方法不能支持整体排序也没关系。
以下是一个QMap 示例,使用字符串(QString)作为键,使用整数(int)作为值:
要向映射中插入一个键值对,你可以使用operator[]()方法:
map[ "one" ] = 1 ;
map[ "three" ] = 3 ;
map[ "seven" ] = 7 ;
以上代码,会向这个 QMap 中插入以下三个键值对:("one", 1)、("three", 3)和("seven", 7)。另一个向映射中插入条目的方法就是insert():
map.insert( "twelve" , 12 );
要查询一个值,可以使用operator[]()或value():
int num1 = map[ "thirteen" ];
int num2 = map.value( "thirteen" );
如果在映射中当前并不存在与指定的键相对应的条目,那么,这些方法会返回一个 默认值 。
要检查映射中是否包含某个特定的键,可以使用contains():
int timeout = 30 ;
if (map.contains( "TIMEOUT" ))
timeout = map.value( "TIMEOUT" );
另外还有一个重载的value()方法,在未能找到与指定的键相关联的条目时,会使用它的第二个参数作为默认值来返回:
int timeout = map.value( "TIMEOUT" , 30 );
通常情况下,我们建议你使用contains()和value()来查询映射中的某个键,而不是使用operator[]()。原因是,如果当前没有条目与指定的键相关联,那么operator[]()会默默地向映射中插入一个条目(除非这个映射本身是常量)。例如,以下代码片断,会在内存中创建1000个条目:
// 错误做法
...
for ( int i = 0 ; i < 1000 ; ++i) {
if (map[i] == okButton)
cout << "Found button at index " << i << endl;
}
要避免这个问题的话,应当在上面的代码中,将map[i]替换成map.value(i)。
要想遍历QMap 中储存的所有键值对,可以使用一个迭代器。QMap同时提供了Java 风格的迭代器 (QMapIterator和QMutableMapIterator)以及 标准模板库风格的迭代器 (QMap::const_iterator和QMap::iterator)。以下是使用Java 风格迭代器来遍历一个QMap<QString, int>的示例:
QMapIterator < QString , int > i(map);
while (i.hasNext()) {
i. next ();
cout << qPrintable (i.key()) << ": " << i.value() << endl;
}
以下代码,做的相同的事情,不过使用的是标准模板库风格的迭代器:
for ( auto i = map.cbegin(), end = map.cend(); != end ; ++i)
cout << qPrintable (i.key()) << ": " << i.value() << endl;
那些条目,会被按照键类型的从小到大的顺序来遍历。
在QMap中,对于特定的键,只允许有一个对应的值。如果你调用insert(),并且指定一个已经存在于 QMap 中的键,那么,之前设置的值会被删除。例如:
map.insert( "plenty" , 100 );
map.insert( "plenty" , 2000 );
// map.value("plenty") == 2000
不过,在QMultiMap中,你可以针对单个键存储多个值。
如果你只是需要从映射中获取那些值(而不关心键),那么,可以使用基于范围的for 循环:
...
for ( int value : std::as_const(map))
cout << value << endl;
有多种方法,可以用于从映射中删除条目。其中一种方法就是调用remove();这会删除与指定的键相关联的任何条目。也可以调用QMutableMapIterator::remove()。另外,可以调用clear()来清空整个映射。
在QMap中,键和值的数据类型都必须是 可赋值的数据类型 。这已经包含了你通常会用到的大部分数据类型了,不过,要注意,某些类型是不被编译器允许使用的,例如,你不能将QWidget作为值来使用;而是应当使用QWidget *。另外,QMap中的键类型,必须提供operator<()方法。QMap使用这个方法来确保它的条目是处于排序状态的,并且它假设,对于两个键x和y来说,如果x < y与y < x都不为真(true),那么,这两个键是等同的。
示例:
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee
{
public :
Employee () {}
Employee ( const QString &name, QDate dateOfBirth);
...
private :
QString myName;
QDate myDateOfBirth;
};
inline bool operator <( const Employee &e1, const Employee &e2)
{
if (e1.name() != e2.name())
return e1.name() < e2.name();
return e1.dateOfBirth() < e2.dateOfBirth();
}
#endif // EMPLOYEE_H
在这个示例中,我们首先比较两个雇员的名字。如果名字是相同的,那么,我们比较两个雇员的生日,以期望分个先后出来。
参考QMapIterator、QMutableMapIterator、QHash和QSet。
返回一个常量的 标准模板库风格的迭代器 ,指向映射中的第一个条目。
返回一个常量的 标准模板库风格的迭代器 指向映射中最后一个实际条目之后的那个虚构的条目。
这是一个重载函数。
与size()相同。
插入一个新的条目,以key作为键,以value作为值。
如果已有某个条目与键key相关联,那么,它的值会被替换为value。
参考QMultiMap::insert()。
这是一个重载函数。
插入一个新的条目,以key作为键,以value作为值,并且以提示的位置pos作为建议的插入位置。
如果使用constBegin()作为提示位置,那就是表示,此处的键key比映射中的任何键都要小。类似地,如果使用constEnd()作为提示位置,那就是表示,此处的键key比映射中的任何键都要(严格地)大。在其它情况下,提示位置必须符合这个条件:(pos - 1).key() < key <= pos.key()。如果提示位置pos是错误的,那么它会被忽略,进而执行一个常规的插入操作。
如果已有某个条目与键key相关联,那么,它的值会被替换为value。
如果提示位置是正确的,并且该映射当前未被共享,那么,此次插入动作的执行时间会是均摊的(amortized) 常量时间 。
当你需要基于一组已排序的数据来创建一个映射时,以constBegin()作为提示位置并且从最大的那个键开始插入,要比以constEnd()作为提示位置并且按照从小到大的顺序来插入要快一些。因为,constEnd() - 1(在检查提示位置是否有效时执行)需要 对数时间 。
注意:谨慎使用提示位置参数。如果你将某个旧的共享的映射实例中的迭代器作为参数提供到这里,可能导致崩溃,也可能,在不崩溃的情况下默默地损坏当前映射和pos参数所从属的那个映射。
参考QMultiMap::insert()。
这是一个重载函数。
返回第一个与值value相关联的键,或是,如果映射中不包含其值为value的条目,则返回默认键defaultKey。如果未提供默认键参数defaultKey,则在对应的情况下这个函数会返回一个 默认构造的键 。
这个函数可能会很慢( 线性时间 ),因为QMap的内部数据结构是针对基于键的快速查询而优化的,而非针对基于值的快速查询而优化的。
返回一个列表,其中会包含这个映射中所有的键,并且以递增顺序排列。
其顺序会确保与values()中使用的顺序相同。
这个函数会在 线性时间 内创建一个新的列表。对于这个过程中所必须耗费的时间和内存,可通过从keyBegin()遍历到keyEnd()来避免。
参考QMultiMap::uniqueKeys()、values()和key()。
这是一个重载函数。
返回一个列表,其中包含所有与值value相关联的键,并且以递增顺序排列。
这个函数可能会很慢( 线性时间 ),因为QMap的内部数据结构是针对基于键的快速查询而优化的,而非针对基于值的快速查询而优化的。
删除映射中所有与键key相关联的条目。返回所删除的条目的个数,如果键存在则是1,否则则是0。
返回映射中键值对的个数。
Your opinionsHxLauncher: Launch Android applications by voice commands