QHash-官翻
QHash 类
template <typename Key, typename T> class QHash
QHash 类是一种模板类,提供基于哈希表的字典类结构。更多内容…
头文件: | #include <QHash> |
---|---|
qmake: | QT += core |
派生类: | QMultiHash |
- 所有成员列表,包括继承的成员
- 废弃的成员
注意: 该类中的所有函数都是可重入的。
公共成员类型
class | const_iterator |
---|---|
class | iterator |
class | key_iterator |
typedef | ConstIterator |
typedef | Iterator |
typedef | const_key_value_iterator |
typedef | difference_type |
typedef | key_type |
typedef | key_value_iterator |
typedef | mapped_type |
typedef | size_type |
公共成员函数
QHash(InputIterator begin, InputIterator end) | |
---|---|
QHash(QHash<K, V> &&other) | |
QHash(const QHash<K, V> &other) | |
QHash(std::initializer_list<std::pair<Key, T> > list) | |
QHash() | |
QHash<K, V> & | operator=(QHash<K, V> &&other) |
QHash<K, V> & | operator=(const QHash<K, V> &other) |
~QHash() | |
QHash::iterator | begin() |
QHash::const_iterator | begin() const |
int | capacity() const |
QHash::const_iterator | cbegin() const |
QHash::const_iterator | cend() const |
void | clear() |
QHash::const_iterator | constBegin() const |
QHash::const_iterator | constEnd() const |
QHash::const_iterator | constFind(const Key &key) const |
QHash::const_key_value_iterator | constKeyValueBegin() const |
QHash::const_key_value_iterator | constKeyValueEnd() const |
bool | contains(const Key &key) const |
int | count(const Key &key) const |
int | count() const |
bool | empty() const |
QHash::iterator | end() |
QHash::const_iterator | end() const |
QPair<QHash::iterator, QHash::iterator> | equal_range(const Key &key) |
QPair<QHash::const_iterator, QHash::const_iterator> | equal_range(const Key &key) const |
QHash::iterator | erase(QHash::const_iterator pos) |
QHash::iterator | erase(QHash::iterator pos) |
QHash::iterator | find(const Key &key) |
QHash::const_iterator | find(const Key &key) const |
QHash::iterator | insert(const Key &key, const T &value) |
void | insert(const QHash<K, V> &other) |
bool | isEmpty() const |
const Key | key(const T &value) const |
const Key | key(const T &value, const Key &defaultKey) const |
QHash::key_iterator | keyBegin() const |
QHash::key_iterator | keyEnd() const |
QHash::key_value_iterator | keyValueBegin() |
QHash::const_key_value_iterator | keyValueBegin() const |
QHash::key_value_iterator | keyValueEnd() |
QHash::const_key_value_iterator | keyValueEnd() const |
QList | keys() const |
QList | keys(const T &value) const |
int | remove(const Key &key) |
void | reserve(int size) |
int | size() const |
void | squeeze() |
void | swap(QHash<K, V> &other) |
T | take(const Key &key) |
const T | value(const Key &key) const |
const T | value(const Key &key, const T &defaultValue) const |
QList | values() const |
bool | operator!=(const QHash<K, V> &other) const |
bool | operator==(const QHash<K, V> &other) const |
T & | operator[](const Key &key) |
const T | operator[](const Key &key) const |
相关非成员函数
int | qGlobalQHashSeed() |
---|---|
uint | qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) |
uint | qHash(const QUrl &url, uint seed = 0) |
uint | qHash(const QOcspResponse &response, uint seed) |
uint | qHash(const QHash<Key, T> &key, uint seed = 0) |
uint | qHash(const QBitArray &key, uint seed = 0) |
uint | qHash(char key, uint seed = 0) |
uint | qHash(const QDateTime &key, uint seed = 0) |
uint | qHash(QSslEllipticCurve curve, uint seed) |
uint | qHash(QLatin1String key, uint seed = 0) |
uint | qHash(uchar key, uint seed = 0) |
uint | qHash(const QDate &key, uint seed = 0) |
uint | qHash(signed char key, uint seed = 0) |
uint | qHash(const QTime &key, uint seed = 0) |
uint | qHash(const QSet &key, uint seed = 0) |
uint | qHash(const T *key, uint seed = 0) |
uint | qHash(ushort key, uint seed = 0) |
uint | qHash(short key, uint seed = 0) |
uint | qHash(uint key, uint seed = 0) |
uint | qHash(const QPair<T1, T2> &key, uint seed = 0) |
uint | qHash(int key, uint seed = 0) |
uint | qHash(const std::pair<T1, T2> &key, uint seed = 0) |
uint | qHash(const QVersionNumber &key, uint seed = 0) |
uint | qHash(ulong key, uint seed = 0) |
uint | qHash(long key, uint seed = 0) |
uint | qHash(quint64 key, uint seed = 0) |
uint | qHash(qint64 key, uint seed = 0) |
uint | qHash(float key, uint seed = 0) |
uint | qHash(double key, uint seed = 0) |
uint | qHash(long double key, uint seed = 0) |
uint | qHash(const Char key, uint seed = 0) |
uint | qHash(const QByteArray &key, uint seed = 0) |
uint | qHash(const QString &key, uint seed = 0) |
uint | qHash(const QStringRef &key, uint seed = 0) |
uint | qHashBits(const void *p, size_t len, uint seed = 0) |
uint | qHashRange(InputIterator first, InputIterator last, uint seed = 0) |
uint | qHashRangeCommutative(InputIterator first, InputIterator last, uint seed = 0) |
void | qSetGlobalQHashSeed(int newSeed) |
QDataStream & | operator<<(QDataStream &out, const QHash<Key, T> &hash) |
QDataStream & | operator>>(QDataStream &in, QHash<Key, T> &hash) |
详细描述
QHash<Key, T> 是一种 Qt 泛型容器类。该类存储键值对,可以用相关联的键非常快速地查找值。
QHash 的功能与 QMap 非常相似。二者的区别在于:
- QHash 的查找速度比 QMap 快。(详情请看算法复杂度 。)
- 遍历 QMap 时,元素总是按照键的顺序排好序的。而遍历 QHash时,元素的顺序是任意的。
- QMap 的键类型必须提供 operator<() 运算符。QHash 的键类型必须提供 operator==() 运算符和名为 qHash() 的全局哈希函数 (参考 qHash 哈希函数)。
下面是一个键类型为 QString,值类型为 int
的 QHash 的示例:
QHash<QString, int> hash;
hash["one"] = 1;
hash["three"] = 3;
hash["seven"] = 7;
上面的代码将3个键值对插入到 QHash 中:(“one”, 1),(“three”, 3) 和 (“seven”, 7)。另外一种向哈希表中插入元素的方法是使用 insert():
hash.insert("twelve", 12);
使用 operator 运算符或 value() 查找值:
int num1 = hash["thirteen"];
int num2 = hash.value("thirteen");
如果哈希表中不存在指定的键,这些函数返回默认构造的值。
如果想检查哈希表中是否包含特定键,使用 contains():
int timeout = 30;
if (hash.contains("TIMEOUT"))timeout = hash.value("TIMEOUT");
还有一个 value() 的重载函数,如果哈希表中不存在指定键的元素,该函数使用第2个参数作为默认值:
int timeout = hash.value("TIMEOUT", 30);
一般推荐使用 contains() 和 value() 而不是 operator 运算符查找哈希表中的键。原因是如果哈希表中不存在相同键的元素,operator 运算符会默默地将一个元素插入到哈希表中(除非哈希表是 const 的)。例如,下面的代码片段将在内存中创建1000个元素:
// 错误
QHash<int, QWidget *> hash;
...
for (int i = 0; i < 1000; ++i) {if (hash[i] == okButton)cout << "Found button at index " << i << Qt::endl;
}
为了避免这个问题,将上面代码中的 hash[i]
替换为 hash.value(i)
。
QHash 内部使用哈希表来执行查找。哈希表自动增长和收缩以保证在不浪费太多内存的情况下快速查找。如果已经大概知道 QHash 将包含多少元素,可以通过调用 reserve() 来控制哈希表的大小,但是不能保证一定获得更好的性能。还可以调用 capacity() 来获取哈希表的大小。
如果想遍历 QHash 中存储的所有键值对,可以使用迭代器。QHash 同时提供 Java 风格迭代器(QHashIterator 和 QMutableHashIterator)和 STL 风格迭代器(QHash::const_iterator 和 QHash::iterator)。下面是使用 Java 风格迭代器遍历 QHash<QString, int> 的方法:
QHashIterator<QString, int> i(hash);
while (i.hasNext()) {i.next();cout << i.key() << ": " << i.value() << Qt::endl;
}
下面是相同的代码,不过这次使用 STL 风格迭代器:
QHash<QString, int>::const_iterator i = hash.constBegin();
while (i != hash.constEnd()) {cout << i.key() << ": " << i.value() << Qt::endl;++i;
}
QHash 是无序的,所以迭代器的顺序是不可预测的。如果需要通过键排序,使用 QMap。
通常,QHash 每个键只允许有一个值。如果用已经存在的键调用 insert(),先前的值将被删除。例如:
hash.insert("plenty", 100);
hash.insert("plenty", 2000);
// hash.value("plenty") == 2000
如果只想从哈希表中获取值(而不是键),也可以使用 foreach:
QHash<QString, int> hash;
...
foreach (int value, hash)cout << value << Qt::endl;
移除元素有几种方法。一种是调用 remove();该函数移除指定键的所有元素。另一种方法是使用 QMutableHashIterator::remove()。另外,还可以使用 clear() 清除整个哈希表。
QHash 键和值的数据类型必须是可赋值数据类型。不能存储 QWidget 作为值;而应该存储 QWidget *。
qHash() 哈希函数
QHash 的键类型除了必须是可赋值数据类型外,还有一个额外要求:它必须提供 operator==() 运算符,并且在键类型的命名空间内还必须有一个为键类型参数返回哈希值的 qHash() 函数。
该 qHash() 函数基于键计算数值。可以使用任何可以想到的算法计算,只要保证相同参数返回相同值就可以。也就是说,如果 e1 == e2
,那么 qHash(e1) == qHash(e2)
也保持成立。然而,为了获得更好的性能,qHash() 函数应该尽最大可能对不同的键返回不同的哈希值。
对于键类型 K
,qHash 函数必须是下面两种签名之一:
uint qHash(K key);
uint qHash(const K &key);uint qHash(K key, uint seed);
uint qHash(const K &key, uint seed);
两个参数的重载函数接受一个无符号整数参数,该参数用来随机化哈希函数的计算。这个种子由 QHash 提供,为了阻止一种算法复杂度攻击。 如果同时定义单参数和两个参数的重载函数,QHash 将使用后者(注意,你可以定义两个参数的版本,并对 seed 参数使用默认值)。
下面是可以在 QHash 中作为键使用的 C++ 和 Qt 类型的不完全列表:任何整数类型(char,unsigned long 等),任何指针类型,QChar,QString 和 QByteArray。对于所有这些类型,<QHash>
头文件会定义 qHash() 函数,该函数计算合适的哈希值。 其它许多 Qt 类也会为其类型声明 qHash 重载函数;具体请参考类文档。
如果想使用其它类型作为键,请确保提供 operator==() 运算符并实现 qHash() 函数。
例子:
#ifndef EMPLOYEE_H
#define EMPLOYEE_Hclass Employee
{
public:Employee() {}Employee(const QString &name, QDate dateOfBirth);...private:QString myName;QDate myDateOfBirth;
};inline bool operator==(const Employee &e1, const Employee &e2)
{return e1.name() == e2.name()&& e1.dateOfBirth() == e2.dateOfBirth();
}inline uint qHash(const Employee &key, uint seed)
{return qHash(key.name(), seed) ^ key.dateOfBirth().day();
}#endif // EMPLOYEE_H
上例中,我们依赖 Qt 的全局 qHash(const QString &, uint) 函数取得雇员名字的哈希值,然后将这个值与雇员的出生日期求异或,来为同名雇员生成各自唯一的哈希值。
注意,Qt 提供的 qHash() 重载函数的实现可能在任何时候改变。一定不能依赖于这个假定,认为不同 Qt 版本的 qHash() 函数(对于相同的输入)会计算出相同的结果。
算法复杂度攻击
所有哈希表都容易受到一种特殊类型的拒绝服务攻击,攻击者预先仔细计算好一组不同的键,用这些键在哈希表的同一个 bucket 中(甚至具有相同哈希值)进行散列。攻击的目的是在数据输入表中时达到最坏情形的算法行为(O(n) 而不是平均的 O(1),详情参考算法复杂度)。
为了避免这种最坏情形的行为,可以在 qHash() 计算哈希值时通过随机种子进行掺杂,抵消攻击的程度。 该种子由 QHash 自动生成,每个进程单独一个,由 QHash 传给两个参数的 qHash() 重载函数的第2个参数。
QHash 的这种随机化处理默认是激活的。尽管如此,使用者不应该依赖于特定的 QHash 顺序,这可能是在调试或回归测试等临时需要这种确定性行为的时候。要想关闭随机化处理,可以将环境变量 QT_HASH_SEED
设置为 0,或者使用参数 0 调用 qSetGlobalQHashSeed() 函数。
另请参阅 QHashIterator, QMutableHashIterator, QMap 和 QSet.
成员类型文档
typedef QHash::ConstIterator
QHash::const_iterator 的 Qt 风格的别名。
typedef QHash::Iterator
QHash::iterator 的 Qt 风格的别名。
typedef QHash::const_key_value_iterator
QMap::const_key_value_iterator 类型定义为 QHash 和 QMultiHash 提供 STL 风格迭代器。
除了 operator*() 运算符返回的是键值对而不是值之外,QHash::const_key_value_iterator 基本和 QHash::const_iterator 相同。
Qt 5.10 中引入该类型定义。
另请参阅 QKeyValueIterator。
typedef QHash::difference_type
ptrdiff_t 的类型别名。为兼容 STL 提供。
typedef QHash::key_type
Key 的类型别名。为兼容 STL 提供。
typedef QHash::key_value_iterator
QHash::key_value_iterator 类型定义为 QHash 和 QMultiHash 提供 STL 风格迭代器。
除了 operator*() 运算符返回的是键值对而不是值之外,QHash::key_value_iterator 基本和 QHash::iterator 相同。
Qt 5.10 中引入该类型定义。
另请参阅 QKeyValueIterator。
typedef QHash::mapped_type
T 的类型别名。为兼容 STL 提供。
typedef QHash::size_type
int 的类型别名。为兼容 STL 提供。
成员函数文档
template QHash::QHash(InputIterator begin, InputIterator end)
用迭代器范围 [begin, end) 内每个元素的副本构造一个哈希表。需要满足下列两个条件之一:迭代范围内的元素是包含 first
和 second
数据成员的对象(像 QPair
,std::pair
等),分别可以转换为 Key
类型和 T
类型;或者迭代器必须含有 key()
和 value()
成员函数,分别返回可以转换为 Key
类型的键和 T
类型的值。
Qt 5.14 中引入该函数。
QHash::QHash(QHash<K, V> &&other)
移动构造一个 QHash 实例,使该实例指向 other 所指向的同一对象。
Qt 5.2 中引入该函数。
QHash::QHash(const QHash<K, V> &other)
构造一个 other 的副本。
该操作需要常数时间,因为 QHash 是隐式共享的。这使得从一个函数返回 QHash 非常快。如果共享实例被修改了,它将以线性时间被复制一份(写时拷贝)。
另请参阅 operator=()。
QHash::QHash(std::initializer_list<std::pair<Key, T> > list)
用初始化列表 list 中每个元素的副本构造一个哈希表。
只有当程序在 C++11 模式下编译时,该函数才可用。
Qt 5.1 中引入该函数。
QHash::QHash()
构造一个空哈希表。
另请参阅 clear()。
QHash<K, V> &QHash::operator=(QHash<K, V> &&other)
移动赋值 other 到该 QHash实例。
Qt 5.2 中引入该函数。
QHash<K, V> &QHash::operator=(const QHash<K, V> &other)
将 other 赋值给该哈希表并返回该哈希表的引用。
QHash::~QHash()
析构哈希表。该哈希表中值的引用及所有该哈希表的迭代器都将失效。
QHash::iterator QHash::begin()
返回 STL 风格迭代器 pointing to the first item in the hash.
另请参阅 constBegin() 和 end()。
QHash::const_iterator QHash::begin() const
这是一个重载函数。
int QHash::capacity() const
返回 QHash 内部哈希表中的 bucket 数。
该函数的唯一目的是提供一种调节 QHash 内存使用的方法。一般很少需要调用该函数。如果想知道哈希表中的元素数,请调用 size()。
另请参阅 reserve() 和 squeeze()。
QHash::const_iterator QHash::cbegin() const
返回常量类型的 STL 风格迭代器,指向哈希表中的第一个元素。
Qt 5.0 中引入该函数。
另请参阅 begin() 和 cend()。
QHash::const_iterator QHash::cend() const
返回常量类型的 STL 风格迭代器,指向哈希表中最后一个元素之后的假想元素。
Qt 5.0 中引入该函数。
另请参阅 cbegin() 和 end()。
void QHash::clear()
从哈希表中移除所有元素。
另请参阅 remove()。
QHash::const_iterator QHash::constBegin() const
返回常量类型的 STL 风格迭代器,指向哈希表中的第一个元素。
另请参阅 begin() 和 constEnd()。
QHash::const_iterator QHash::constEnd() const
返回常量类型的 STL 风格迭代器,指向哈希表中最后一个元素之后的假想元素。
另请参阅 constBegin() 和 end()。
QHash::const_iterator QHash::constFind(const Key &key) const
返回常量类型(译者注:原文没有const)的迭代器,指向哈希表中键为 key 的元素。
如果哈希表不包含键为 key 的元素,该函数返回 constEnd()。
Qt 4.1 中引入该函数。
另请参阅 find() 和 QMultiHash::constFind()。
QHash::const_key_value_iterator QHash::constKeyValueBegin() const
返回常量类型的 STL 风格迭代器,指向哈希表中的第一项.
Qt 5.10 中引入该函数。
另请参阅 keyValueBegin()。
QHash::const_key_value_iterator QHash::constKeyValueEnd() const
返回常量类型的 STL 风格迭代器,指向哈希表中最后一项之后的假想项。
Qt 5.10 中引入该函数。
另请参阅 constKeyValueBegin()。
bool QHash::contains(const Key &key) const
如果该哈希表包含键为 key 的元素,返回 true
;否则返回 false
。
另请参阅 count() 和 QMultiHash::contains()。
int QHash::count(const Key &key) const
返回与键 key 相关联的元素个数。
另请参阅 contains() 和 insertMulti()。
int QHash::count() const
这是一个重载函数。
同 size()。
bool QHash::empty() const
该函数为兼容 STL 提供。与 isEmpty() 等价,如果哈希表为空,返回 true
;否则返回 false
。
QHash::iterator QHash::end()
返回 STL 风格迭代器,指向哈希表中最后一个元素之后的假想元素。
另请参阅 begin() 和 constEnd()。
QHash::const_iterator QHash::end() const
这是一个重载函数。
QPair<QHash::iterator, QHash::iterator> QHash::equal_range(const Key &key)
返回一对迭代器界定与 key 相关联的值的范围 [first, second)
。如果范围为空,则两个迭代器都为 end()。
Qt 5.7 中引入该函数。
QPair<QHash::const_iterator, QHash::const_iterator> QHash::equal_range(const Key &key) const
这是一个重载函数。
Qt 5.7 中引入该函数。
QHash::iterator QHash::erase(QHash::const_iterator pos)
从哈希表中移除迭代器 pos 指向的键值对,返回指向哈希表中下一个元素的迭代器。
与 remove() 和 take() 不同,该函数绝不会使 QHash 重新散列其内部数据结构。这意味着可以在迭代时安全调用该函数而不会影响哈希表中元素的顺序。例如:
QHash<QObject *, int> objectHash;
...
QHash<QObject *, int>::iterator i = objectHash.find(obj);
while (i != objectHash.end() && i.key() == obj) {if (i.value() == 0) {i = objectHash.erase(i);} else {++i;}
}
Qt 5.7 中引入该函数。
另请参阅 remove(),take() 和 find()。
QHash::iterator QHash::erase(QHash::iterator pos)
这是一个重载函数。
QHash::iterator QHash::find(const Key &key)
返回迭代器,指向哈希表中键为 key 的元素。
如果哈希表不包含键为 key 的元素,函数返回 end().
如果哈希表包含多个键为 key 的元素,函数返回指向最新插入的那个值的迭代器。其它值可以通过递增迭代器取得。例如,下面的代码遍历同一键的所有元素:
QHash<QString, int> hash;
...
QHash<QString, int>::const_iterator i = hash.find("HDR");
while (i != hash.end() && i.key() == "HDR") {cout << i.value() << Qt::endl;++i;
}
另请参阅 value(),values() 和 QMultiHash::find()。
QHash::const_iterator QHash::find(const Key &key) const
这是一个重载函数。
QHash::iterator QHash::insert(const Key &key, const T &value)
用键 key 和值 value 插入一个新元素。
如果已经存在键为 key 的元素,该元素的值将被 value 替换。
如果有多个键为 key 的元素,最新插入的元素的值将被 value 替换。
void QHash::insert(const QHash<K, V> &other)
将 other 哈希表中的所有元素插入到本哈希表中。
如果一个键同时在两个哈希表中出现,其值将被 other 中存储的值替换。
注意: 如果 other 中同一键关联多个元素,则该键的最终值未定义。
Qt 5.15 中引入该函数。
bool QHash::isEmpty() const
如果哈希表中不包含元素,返回 true
;否则返回 false
。
另请参阅 size()。
const Key QHash::key(const T &value) const
返回与值 value 对应的第一个键。
如果哈希表不包含值为 value 的元素,函数返回默认构造的键.
该函数可能会比较慢(线性时间),因为 QHash 的内部数据结构是以快速查找键而不是值为目标来优化的。
另请参阅 value() 和 keys()。
const Key QHash::key(const T &value, const Key &defaultKey) const
这是一个重载函数。
返回与值 value 对应的第一个键,如果哈希表不包含值为 value 的元素,返回 defaultKey。
该函数可能会比较慢(线性时间),因为 QHash 的内部数据结构是以快速查找键而不是值为目标来优化的。
Qt 4.3 中引入该函数。
QHash::key_iterator QHash::keyBegin() const
返回常量类型的 STL 风格迭代器,指向哈希表中的第一个键。
Qt 5.6 中引入该函数。
另请参阅 keyEnd()。
QHash::key_iterator QHash::keyEnd() const
返回常量类型的 STL 风格迭代器,指向哈希表中的最后一个元素之后的假想元素的键。
Qt 5.6 中引入该函数。
另请参阅 keyBegin()。
QHash::key_value_iterator QHash::keyValueBegin()
返回 STL 风格迭代器,指向哈希表中的第一项。
Qt 5.10 中引入该函数。
另请参阅 keyValueEnd()。
QHash::const_key_value_iterator QHash::keyValueBegin() const
返回常量类型的 STL 风格迭代器,指向哈希表中的第一项。
Qt 5.10 中引入该函数。
另请参阅 keyValueEnd()。
QHash::key_value_iterator QHash::keyValueEnd()
返回 STL 风格迭代器,指向哈希表中最后一项之后的假想项。
Qt 5.10 中引入该函数。
另请参阅 keyValueBegin()。
QHash::const_key_value_iterator QHash::keyValueEnd() const
返回常量类型的 STL 风格迭代器,指向哈希表中最后一项之后的假想项。
Qt 5.10 中引入该函数。
另请参阅 keyValueBegin()。
QList QHash::keys() const
以任意顺序返回哈希表中所有键的列表。在哈希表中多次出现的键(当该方法应用在 QMultiHash 时)也会在列表中多次出现。
键的顺序将确保与通过 values() 返回的值的顺序相同。
另请参阅 QMultiMap::uniqueKeys(),values() 和 key()。
QList QHash::keys(const T &value) const
这是一个重载函数。
以任意顺序返回所有与值 value 相关联的键的列表。
该函数可能会比较慢(线性时间),因为 QHash 的内部数据结构是以快速查找键而不是值为目标来优化的。
int QHash::remove(const Key &key)
从哈希表中移除所有键为 key 的元素。返回被移除的元素个数,如果键存在,则为1,否则为0。
另请参阅 clear(),take() 和 QMultiHash::remove()。
void QHash::reserve(int size)
确保 QHash 的内部哈希表包含至少 size 数量的 bucket。
该函数对于需要构建大型哈希表,并且不想重复分配内存的使用者来说很有用。例如:
QHash<QString, int> hash;
hash.reserve(20000);
for (int i = 0; i < 20000; ++i)hash.insert(keys[i], values[i]);
理想情况下,size 应该比哈希表中期望的最大元素数略大。size 不一定必须是质数,因为 QHash 内部总会使用一个质数。如果 size 预估小了,可能发生的最坏情形就是 QHash 会变慢一点。
一般很少需要调用该函数。QHash 的内部哈希表会自动收缩或增长来保证不浪费太多内存的情况下达到最优性能。
另请参阅 squeeze() 和 capacity()。
int QHash::size() const
返回哈希表中的元素个数。
另请参阅 isEmpty() 和 count()。
void QHash::squeeze()
减少 QHash 内部哈希表的大小以节约内存。
该函数的唯一目的是提供一种调节 QHash 内存使用的方法。一般很少需要调用该函数。
另请参阅 reserve() 和 capacity()。
void QHash::swap(QHash<K, V> &other)
将哈希表 other 与本哈希表。该操作非常快,永远不失败。
Qt 4.8 中引入该函数。
T QHash::take(const Key &key)
从哈希表中移除键为 key 的元素,返回键 key 所关联的值。
如果哈希表中不存在该元素,该函数简单返回一个默认构造的值。如果哈希表中有多个键为 key 的元素,只移除最新插入的元素并返回值。
如果不使用返回值,使用 remove() 更高效一些。
另请参阅 remove()。
const T QHash::value(const Key &key) const
返回键 key 关联的值。
如果哈希表不包含键为 key 的元素,该函数返回默认构造的值。如果哈希表中有多个键为 key 的元素,返回最新插入的元素的值。
另请参阅 key(),values(),contains() 和 [operator]()。
const T QHash::value(const Key &key, const T &defaultValue) const
这是一个重载函数。
如果哈希表不包含键为 key 的元素,该函数返回 defaultValue。
QList QHash::values() const
以任意顺序返回哈希表中所有值的列表。如果一个键关联到多个值,该键的所有值都将被放入列表中,而不只是最新插入的值。
顺序将确保与通过 keys() 返回的键的顺序相同。
另请参阅 keys() 和 value()。
bool QHash::operator!=(const QHash<K, V> &other) const
如果 other 与本哈希表不相等,返回 true
,否则返回 false
。
如果两个哈希表包含相同的键值对,则认为二者相等。
该函数需要值类型实现 operator==()
。
另请参阅 operator==()。
bool QHash::operator==(const QHash<K, V> &other) const
如果 other 与本哈希表相等,返回 true
,否则返回 false
。
如果两个哈希表包含相同的键值对,则认为二者相等。
该函数需要值类型实现 operator==()
。
另请参阅 operator!=()。
T &QHash::operator[](const Key &key)
返回键 key 所关联的值的可修改引用。
如果哈希表不包含键为 key 的元素,该函数用键 key 插入一个默认构造的值,并返回该值的引用。如果哈希表包含多个键为 key 的元素,该函数返回最新插入的那个值的引用。
另请参阅 insert() 和 value()。
const T QHash::operator[](const Key &key) const
这是一个重载函数。
同 value()。
相关非成员函数
int qGlobalQHashSeed()
返回当前全局 QHash 种子。
任何新创建的 QHash 都会设置该种子。请参考 qHash 了解 QHash 如何使用该种子。
Qt 5.6 中引入该函数。
另请参阅 qSetGlobalQHashSeed。
uint qHash(const QUrl &url, uint seed = 0)
返回 url 的哈希值。如果指定了 seed,该值用于初始化哈希表。
Qt 5.0 中引入该函数。
template <typename Key, typename T> uint qHash(const QHash<Key, T> &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来 seed 计算。
类型 T
必须被 qHash() 支持。
Qt 5.8 中引入该函数。
uint qHash(const QBitArray &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(char key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(const QDateTime &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(QLatin1String key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(uchar key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(const QDate &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(signed char key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(const QTime &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
template uint qHash(const QSet &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
哈希值不依赖于 key 中元素的顺序,即包含相同元素的 set 散列相同的值。
Qt 5.5 中引入该函数。
template uint qHash(const T *key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(ushort key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(short key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(uint key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
template <typename T1, typename T2> uint qHash(const QPair<T1, T2> &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
类型 T1
和 T2
必须被 qHash() 支持。
Qt 5.0 中引入该函数。
uint qHash(int key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
template <typename T1, typename T2> uint qHash(const std::pair<T1, T2> &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
类型 T1
和 T2
必须被 qHash() 支持。
注意: 该函数的返回类型与下面函数调用的返回类型不同 :
qHash(qMakePair(key.first, key.second), seed);
两个函数使用不同的哈希算法;因为二进制兼容的限制,我们不能在 Qt 6 之前修改 QPair 算法使其与 std::pair 保持一致。
Qt 5.7 中引入该函数。
uint qHash(const QVersionNumber &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.6 中引入该函数。
uint qHash(ulong key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(long key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(quint64 key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(qint64 key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(float key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.3 中引入该函数。
uint qHash(double key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.3 中引入该函数。
uint qHash(long double key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.3 中引入该函数。
uint qHash(const QChar key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(const QByteArray &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(const QString &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHash(const QStringRef &key, uint seed = 0)
返回 key 的哈希值,使用 seed 来随机化计算结果。
Qt 5.0 中引入该函数。
uint qHashBits(const void *p, size_t len, uint seed = 0)
返回 p 指向的大小为 len 的内存块的哈希值,使用 seed 来随机化计算结果。
仅使用该函数为自定义类型实现 qHash() 函数。例如,下面是一个如何为 std::vector 实现 qHash() 函数的例子:
inline uint qHash(const std::vector<int> &key, uint seed = 0)
{if (key.empty())return seed;elsereturn qHashBits(&key.front(), key.size() * sizeof(int), seed);
}
上面的例子利用了 std::vector 连续存储数据的优势。如果不是这种情况,或者包含的类型 has padding,应该使用 qHashRange()。
需要再次强调,qHashBits() 的实现 - 与 Qt 提供的 qHash() 函数一样 - 可能在任何时候改变。一定不能 依赖于这个假定,认为不同 Qt 版本的 qHashBits() 函数(对于相同的输入)会计算出相同的结果。
Qt 5.4 中引入该函数。
另请参阅 qHashRange() 和 qHashRangeCommutative()。
template uint qHashRange(InputIterator first, InputIterator last, uint seed = 0)
返回范围 [first,last) 的哈希值,使用 seed 来随机化计算结果,该函数依次对每个元素执行 qHash(),然后将所有哈希值组合成一个值。
该函数的返回值依赖于范围中元素的顺序。这意味着
{0, 1, 2}
和
{1, 2, 0}
散列成不同的 值。如果顺序不重要,例如,对于哈希表,要使用 qHashRangeCommutative()。如果想散列原始内存,使用 qHashBits()。
仅使用该函数为自定义类型实现 qHash() 函数。例如,下面是一个如何为 std::vector 实现 qHash() 函数的例子:
inline uint qHash(const std::vector<int> &key, uint seed = 0)
{return qHashRange(key.begin(), key.end(), seed);
}
需要再次强调,qHashRange() 的实现 - 与 Qt 提供的 qHash() 函数一样 - 可能在任何时候改变。一定不能 依赖于这个假定,认为不同 Qt 版本的 qHashRange() 函数(对于相同的输入)会计算出相同的结果,即使该元素类型的 qHash() 函数可以。
Qt 5.5 中引入该函数。
另请参阅 qHashBits() 和 qHashRangeCommutative()。
template uint qHashRangeCommutative(InputIterator first, InputIterator last, uint seed = 0)
返回范围 [first,last) 的哈希值,使用 seed 来随机化计算结果,该函数依次对每个元素执行 qHash(),然后将所有哈希值组合成一个值。
该函数的返回值不依赖于范围中元素的顺序。这意味着
{0, 1, 2}
和
{1, 2, 0}
散列成相同的 值。如果顺序重要,例如,对于 vector 和数组, 要使用 qHashRange()。如果想散列原始内存,使用 qHashBits()。
仅使用该函数为自定义类型实现 qHash() 函数。例如,下面是一个如何为 std::unordered_set 实现 qHash() 函数的例子:
inline uint qHash(const std::unordered_set<int> &key, uint seed = 0)
{return qHashRangeCommutative(key.begin(), key.end(), seed);
}
需要再次强调,qHashRangeCommutative() 的实现 - 与 Qt 提供的 qHash() 函数一样 - 可能在任何时候改变。一定不能 依赖于这个假定,认为不同 Qt 版本的 qHashRangeCommutative() 函数(对于相同的输入)会计算出相同的结果,即使该元素类型的 qHash() 函数可以。
Qt 5.5 中引入该函数。
另请参阅 qHashBits() 和 qHashRange()。
void qSetGlobalQHashSeed(int newSeed)
将全局 QHash 种子设置为 newSeed。
只有在测试和调试时才需要手动设置全局 QHash 种子值,此时需要 QHash 具有确定的和可复制的行为。我们不鼓励在产品代码中这么做因为这会使软件容易受到 算法复杂度攻击。
从 Qt 5.10 开始,只能在 0 和 -1 之间设置值。传递 -1 将重新初始化全局 QHash 种子为一个随机值,传递 0 用来为 C++ 基本类型(例如 int
)和字符串类型(QString,QByteArray)请求稳定算法。
任何新创建的 QHash 都会设置种子值。参考 qHash 了解 QHash 如何使用种子。
如果设置了环境变量 QT_HASH_SEED
,调用该函数什么也不做。
Qt 5.6 中引入该函数。
另请参阅 qGlobalQHashSeed。
template <typename Key, typename T> QDataStream &operator<<(QDataStream &out, const QHash<Key, T> &hash)
将哈希表 hash 写出到流 out。
该函数需要键和值类型实现 operator<<()
。
另请参阅 Serializing Qt Data Types。
template <typename Key, typename T> QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash)
从流 in 读入数据到哈希表 hash。
该函数需要键和值类型实现 operator>>()
。
另请参阅 Serializing Qt Data Types。
相关文章:

QHash-官翻
QHash 类 template <typename Key, typename T> class QHash QHash 类是一种模板类,提供基于哈希表的字典类结构。更多内容… 头文件:#include <QHash>qmake:QT core派生类:QMultiHash 所有成员列表,包括继承的成员废弃的成员 注意&…...

MYSQL 配置优化
max_connections 允许客户端并发连接的最大数量,默认值是151。 show status like %connections%; 设置参数值应大于Max_used_connections。如果使用连接池,可参考连接池的最大连接数和每个连接池的数量作为参考设置 innodb_buffe_pool_instances Inno…...

多 态
1多态的基本概念多态是C面向对象三大特性之一多态分为两类静态多态: 函数重载和运算符重载属于静态多态,复用函数名动态多态: 派生类和虚函数实现运行时多态静态多态和动态多态区别:静态多态的函数地址早绑定–--编译阶段确定函数地址动态多态的函数地址晚绑定–--运…...

Java集合
集合、数组都是对多个数据进行存储操作的结构,简称java容器 (此时的存储,主要指的是内存层面的存储,不涉及持久化的存储) 数组存储的特点: 一旦初始化,其长度就确定了。数组一旦定义好&#x…...

高校借力泛微,搭建一体化、流程化的内控管理平台
财政部《行政事业单位内部控制规范(试行)》中明确规定:行政事业单位内部控制是指通过制定制度、实施措施和执行程序,实现对行政事业单位经济活动风险的防范和管控,包括对其预算管理、收支管理、采购管理、资产管理、建…...

使用人工智能赚钱的方式,行业领域有哪些?
使用人工智能赚钱的方式,行业领域有哪些?不少于2000字。 一、人工智能的应用领域 1、金融服务:金融服务行业是人工智能应用的领域之一,它可以帮助银行、信用卡公司等金融机构实现快速、有效的贷款审批,以及客户分析、…...

【数组中重复的数字】-C语言-题解
原题链接:数组中重复的数字 一、描述: 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数…...

C++调用Python脚本进行18次循环操作后,脚本不执行
C调用Python脚本进行18次循环操作后,脚本不执行 现象: 发送端接收端 从第二张图中可以看出,python脚本卡在’[parkin_debug] 6’与’[parkin_debug] 7’之间 该测试经过多次反复测试,均在第18次循环执行时,出现上述问…...

字节10年架构师职业发展经历,助你做好职业规划
一直以来程序员这一职业都给人高薪资的印象,近年来随着互联网行业的快速发展,程序员更是人满为患,然而很多人关注的却是程序员的薪资,而非职业本身。 一批批程序员进入工作岗位,但是很多人并没有对自己的职业生涯有清…...

ArrayList真的是因为实现了RandomAccess接口才能做到快速随机访问的吗
ArrayList和RandomAccess接口RandomAccess 接口Collections.binarySearch()源码总结RandomAccess 接口 首先,RandomAccess接口是什么,以下代码可见: public interface RandomAccess { }RandomAccess接口其实是一个标记接口,它只…...

OSI七层模型与物理层与设备链路层
目录 协议 举例 OSI七层模型 理解七层模型 以下为OSI七层模型数据逐层封装和数据逐层解封的过程 TCP/IP参考模型 数据包的层层封装与层层拆包 各层的数据以及协议 封装所用的协议的数字表示形式 物理层 模拟信号 模拟信号特点 数字信号 数字信号特点 数据通信模…...

Java8的Optional类的使用 和 Stream流式操作
Java知识点总结:想看的可以从这里进入 目录13.6、Optional类13.7、Stream13.7.1、Stream创建13.7.2、中间操作1、筛选2、切片3、映射4、排序13.7.3、终止操作1、遍历2、聚合3、匹配查找4、归约5、收集归集统计分组字符串拼接归约13.6、Optional类 Optional类是一个…...

Authorization Server 认证服务
Hi Auth HiAuth是一个开源的基于Oauth2协议的认证、授权系统,除了标准的Oauth2授权流程功能外,还提供了应用管理、用户管理、权限管理等相关功能。 在这个项目中你能够了解到如何基于spring-security-oauth2-authorization-server实现自己的Authorizat…...

研制过程评审活动(五)生产定型阶段
1. 生产定型阶段主要任务 生产定型的主要任务是对产品批量生产条件和质量稳定情况进行全面考核,以确认产品是否达到批量生产的标准。 需要生产定型的军工产品,在完成设计定型并经小批量试生产后、正式批量生产之前,进行生产定型。生产定型的条件和时间,由定委在批准设计…...

NCUT加权的NMF
矩阵定义 X:特征矩阵,矩阵的维度为体素数mx(指标数x被试数)n S:相似性矩阵,由特征矩阵的每一行计算皮尔逊相关得到mxm的方阵 D:度矩阵,度矩阵的对角线元素由相似性矩阵S对应的行和…...

从0开始的ios自动化测试
最近由于工作内容调整,需要开始弄ios自动化了。网上信息有点杂乱,这边我就按我的实际情况,顺便记录下来,看是否能帮到有需要的人。 环境准备 安装tidevice pip3 install -U “tidevice[openssl]” 它的作用是,帮你绕…...

vue3中使用jszip压缩文件
1、安装依赖 npm install jszip npm install file-saver --save 2、使用 <template><el-card class"mb15"><template #header><span>jszip</span></template><!-- 二维码容器 --><div id"qrCodeBox">&…...

React 虚拟DOM的前世今生
引文 通过本文你将了解到 什么是虚拟DOM?虚拟DOM有什么优势?React的虚拟Dom是如何实现的?React是如何将虚拟Dom转变为真实Dom? 一、前言 要了解虚拟DOM,我们先明确一下DOM的概念。 根据MDN的说法: 文档…...

Java环境变量配置
一、Path环境变量配置设置环境变量的值:C:\Program Files\Java\jdk-17\bin目前较新的JDK安装时会自动配置javac、java程序的路径到Path环境变量中去 ,因此,javac、java可以直接使用。注意:以前的老版本的JDK在安装的是没有自动配置…...

超详细解读!数据库表分区技术全攻略
更多内容可以关注微信公众号:老程序员刘飞 分区的定义 分区是一种数据库优化技术,它可以将大表按照一定的规则分成多个小表,从而提高查询和维护的效率。在分区的过程中,数据库会将数据按照分区规则分配到不同的分区中࿰…...

Redis高可用集群方案
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 @[TOC](文章目录)主从复制哨兵模式(sentinel)Cluster集群在生产过程中,Redis不一定会单独部署。因为一旦redis服务因为某些原因导致无法提供数,那么redis就不可用了。那么实现redis高可用的方式就…...

企业微信机器人发送消息
前言 随着科技的发展,各企业公司的业务不断发展,那么就需要强有力的沟通软件,其中企业微信、钉钉的能力得到了大众的认可,今天这篇文章就讲其中的一个功能-调用企业微信机器人(下文简称应用)进行消息传递。它的好处有哪些呢?自然是可以让相关人员及时追踪任务进度。 一、…...

使用PHP+yii2调用asmx服务接口
一.创建服务端 1:创建一个ASP.NET web应用程序 2:选择空的模板 3:系统生成项目目录 4:右键项目-添加项-新建项 5:选择Web 服务(ASMX) 6:选择之后项目中会有一个Test.asmx服务程序,…...

【042】904. 水果成篮[滑动窗口]
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果&…...

Linux基础知识(一)
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...

Redis面试题
目录 Redis持久化机制:RDB和AOF Redis线程模型有哪些?单线程为什么快? Redis的过期键有哪些删除策略? Redis集群方案有哪些? redis事务怎么实现? 为什么redis不支持回滚? redis主从复制的原理是什么 …...

微服务之Eureka
🏠个人主页:阿杰的博客 💪个人简介:大家好,我是阿杰,一个正在努力让自己变得更好的男人👨 目前状况🎉:24届毕业生,奋斗在找实习的路上🌟 …...

日日顺于贞超:供应链数字化要做到有数、有路、有人
在供应链行业里面,关于“数字化”的讨论绝对是一个经久不衰的话题。 但关于这个话题的讨论又时常让人觉得“隔靴搔痒”,因为数字化变革为非一日之功,对于企业来说意味着投入和牺牲。企业既怕不做怕将来被淘汰,又怕投入过高、不达预…...

Js中blob、file、FormData、DataView、TypedArray
引言 最开始我们看网页时,对网页的需求不高,显示点文字,显示点图片就很满足了,所以对于浏览器而言其操作的数据其实并不多(比如读取本地图片显示出来,或上传图片到服务器),那么浏览器…...

CTFer成长之路之任意文件读取漏洞
任意文件读取漏洞CTF 任意文件读取漏洞 afr_1 题目描述: 暂无 docker-compose.yml version: 3.2services:web:image: registry.cn-hangzhou.aliyuncs.com/n1book/web-file-read-1:latestports:- 80:80启动方式 docker-compose up -d 题目Flag n1book{afr_1_solved} W…...