QHash类

template <typename Key, typename T> class QHash

QHash类是一个模板类,它提供了一个基于哈希表的字典。 更多...

头文件 #include <QHash>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core

注意:本类中所有函数均可重入

公共类型

公共函数

QHash()
QHash(std::initializer_list<std::pair<Key, T>> list)
QHash(InputIterator begin, InputIterator end)
QHash(const QHash<Key, T> &other)
QHash(QHash<Key, T> &&other)
~QHash()
(since 6.4) autoasKeyValueRange() &
(since 6.4) autoasKeyValueRange() const &
(since 6.4) autoasKeyValueRange() &&
(since 6.4) autoasKeyValueRange() const &&
QHash<Key, T>::iteratorbegin()
QHash<Key, T>::const_iteratorbegin() const
qsizetypecapacity() const
QHash<Key, T>::const_iteratorcbegin() const
QHash<Key, T>::const_iteratorcend() const
voidclear()
QHash<Key, T>::const_iteratorconstBegin() const
QHash<Key, T>::const_iteratorconstEnd() const
QHash<Key, T>::const_iteratorconstFind(const Key &key) const
QHash<Key, T>::const_key_value_iteratorconstKeyValueBegin() const
QHash<Key, T>::const_key_value_iteratorconstKeyValueEnd() const
boolcontains(const Key &key) const
qsizetypecount(const Key &key) const
qsizetypecount() const
QHash<Key, T>::iteratoremplace(const Key &key, Args &&... args)
QHash<Key, T>::iteratoremplace(Key &&key, Args &&... args)
boolempty() const
QHash<Key, T>::iteratorend()
QHash<Key, T>::const_iteratorend() const
QHash<Key, T>::iteratorerase(QHash<Key, T>::const_iterator pos)
QHash<Key, T>::iteratorfind(const Key &key)
QHash<Key, T>::const_iteratorfind(const Key &key) const
QHash<Key, T>::iteratorinsert(const Key &key, const T &value)
voidinsert(const QHash<键, T>&& other)
boolisEmpty() const
key(const T& value) const
key(const T& value, const 键& defaultKey) const
QHash<键, T>::key_iteratorkeyBegin() const
QHash<键, T>::key_iteratorkeyEnd() const
QHash<键, T>::key_value_iteratorkeyValueBegin()
QHash<Key, T>::const_key_value_iteratorkeyValueBegin() const
QHash<键, T>::key_value_iteratorkeyValueEnd()
QHash<Key, T>::const_key_value_iteratorkeyValueEnd() const
QList<键>keys() const
QList<键>keys(const T& value) const
浮点数load_factor() const
boolremove(const 键& key)
(自 6.1) qsizetyperemoveIf(Predicate pred)
voidreserve(qsizetype size)
qsizetypesize() const
voidsqueeze()
voidswap(QHash<键, T>&& other)
Ttake(const 键& key)
Tvalue(const 键& key) const
Tvalue(const 键& key, const T& defaultValue) const
QListvalues() const
booloperator!=(const QHash<键, T>&& other) const
QHash<键, T>&&operator=(const QHash<键, T>&& other)
QHash<键, T>&&operator=(QHash<键, T>&& other)
booloperator==(const QHash<键, T>&& other) const
T&&operator[](const 键& key)
const Toperator[](const 键& key) const
(自 6.1) qsizetypeerase_if(QHash<键, T>&& hash, Predicate pred)
size_tqHash(const QUrl& url, size_t seed = 0)
size_tqHash(const QStringRef& key, size_t seed)
size_tqHash(const QMqttTopicFilter& filter, size_t seed)
size_tqHash(const QSslDiffieHellmanParameters& dhparam, size_t seed)
size_tqHash(const QGeoLocation& location, size_t seed)
size_tqHash(const QMqttTopicName& name, size_t seed)
size_tqHash(const QOcspResponse& response, size_t seed)
size_tqHash(const QGeoCoordinate& coordinate, size_t seed)
size_tqHash(const QHash<键, T>&& key, size_t seed = 0)
(自 6.0) size_tqHash(QPoint key, size_t seed = 0)
size_tqHash(const QSet&& key, size_t seed = 0)
(自 6.0) size_tqHash(const QTypeRevision& key, size_t seed = 0)
size_tqHash(const QVersionNumber& key, size_t seed = 0)
size_tqHash(const QSslCertificate& key, size_t seed)
size_tqHash(const QGeoShape &shape, size_t seed)
size_tqHash(QSslEllipticCurve curve, size_t seed)
size_tqHash(const QSslError &key, size_t seed)
size_tqHash(const QDateTime &key, size_t seed = 0)
size_tqHash(QDate key, size_t seed = 0)
size_tqHash(QTime key, size_t seed = 0)
size_tqHash(const std::pair<T1, T2> &key, size_t seed = 0)
size_tqHash(char key, size_t seed = 0)
size_tqHash(uchar key, size_t seed = 0)
size_tqHash(signed char key, size_t seed = 0)
size_tqHash(ushort key, size_t seed = 0)
size_tqHash(short key, size_t seed = 0)
size_tqHash(uint key, size_t seed = 0)
size_tqHash(int key, size_t seed = 0)
size_tqHash(ulong key, size_t seed = 0)
size_tqHash(long key, size_t seed = 0)
size_tqHash(quint64 key, size_t seed = 0)
size_tqHash(qint64 key, size_t seed = 0)
(自 6.0) size_tqHash(char8_t key, size_t seed = 0)
(自 6.0) size_tqHash(char16_t key, size_t seed = 0)
(自 6.0) size_tqHash(char32_t key, size_t seed = 0)
(自 6.0) size_tqHash(wchar_t key, size_t seed = 0)
size_tqHash(float key, size_t seed = 0)
size_tqHash(double key, size_t seed = 0)
size_tqHash(long double key, size_t seed = 0)
size_tqHash(const QChar key, size_t seed = 0)
size_tqHash(const QByteArray &key, size_t seed = 0)
size_tqHash(const QBitArray &key, size_t seed = 0)
size_tqHash(const QString &key, size_t seed = 0)
size_tqHash(QLatin1StringView key, size_t seed = 0)
size_tqHash(const T *key, size_t seed = 0)
(自 6.0) size_tqHash(std::nullptr_t key, size_t seed = 0)
size_tqHashBits(const void *p, size_t len, size_t seed = 0)
(自 6.0) size_tqHashMulti(size_t seed, const T &... args)
(自 6.0) size_tqHashMultiCommutative(size_t seed, const T &... args)
size_tqHashRange(InputIterator first, InputIterator last, size_t seed = 0)
size_tqHashRangeCommutative(InputIterator first, InputIterator last, size_t seed = 0)
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的键类型必须提供运算符<()。QHash的键类型必须提供运算符==()和一个名为qHash()的全局哈希函数(见qHash)。

以下是一个示例QHash,具有QString键和int值

QHash<QString, int> hash;

要将(键,值)对插入到哈希中,可以使用operator[]()运算符

hash["one"] = 1;
hash["three"] = 3;
hash["seven"] = 7;

这将以下三个(键,值)对插入到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(),如果没有指定键的项目,则使用其第二个参数作为默认值

int timeout = hash.value("TIMEOUT", 30);

通常,我们建议您使用contains()和value()而不是operator[]()在哈希中查找键。原因是如果不存在具有相同键的项,则operator[]()(除非哈希是const)会静默地将项插入到哈希中。例如,下面的代码片段将在内存中创建1000个项目

// WRONG
QHash<int, QWidget *> hash;
...
for (int i = 0; i < 1000; ++i) {
    if (hash[i] == okButton)
        cout << "Found button at index " << i << endl;
}

为了避免这个问题,请在上面的代码中将hash[i]替换为hash.value(i)

内部,QHash使用散列表执行查找。该散列表将自动增长,以提供快速的查找而不会浪费太多内存。如果您已经知道QHash将包含大约多少项,则可以通过调用reserve()来控制散列表的大小,但这不是获得良好性能的必要条件。您还可以调用capacity()以检索散列表的大小。

如果从表中删除项目,QHash不会自动缩小。为了最大限度地减少哈希使用的内存,请调用squeeze()。

如果想要遍历存储在QHash中的所有(键,值)对,可以使用迭代器。QHash提供Java-style iteratorsQHashIteratorQMutableHashIterator)以及STL-style iteratorsQHash::const_iteratorQHash::iterator)。以下是如何使用Java-style迭代器迭代QHash<QString,int>的示例

QHashIterator<QString, int> i(hash);
while (i.hasNext()) {
    i.next();
    cout << qPrintable(i.key()) << ": " << i.value() << endl;
}

以下是相同的代码,但使用STL-style迭代器

for (auto i = hash.cbegin(), end = hash.cend(); i != end; ++i)
    cout << qPrintable(i.key()) << ": " << i.value() << endl;

QHash是无序的,因此迭代器的顺序不能被认为是可预测的。如果需要按键排序,请使用QMap

QHash只允许每个键一个值。如果用已经存在于QHash中的键调用insert(),则先前的值将被删除。例如

hash.insert("plenty", 100);
hash.insert("plenty", 2000);
// hash.value("plenty") == 2000

如果您需要在散列表中存储相同键的多个条目,请使用QMultiHash

如果您只需从散列中提取值(而非键),您也可以使用基于范围的for循环。

QHash<QString, int> hash;
...
for (int value : std::as_const(hash))
    cout << value << endl;

可以从散列表以多种方式删除项目。一种方式是调用remove();这将删除具有给定键的任何项目。另一种方式是使用QMutableHashIterator::remove()。此外,您还可以使用clear()清除整个散列表。

QHash的键和值数据类型必须是可赋值的数据类型。例如,您不能将QWidget作为值存储;相反,存储一个QWidget *。

散列函数

除了必须是可赋值的数据类型之外,QHash的键类型还有其他要求:它必须提供operator==()运算符,还必须有一个用于计算键类型参数的散列值的散列函数。

散列函数根据键计算一个数值。它可以使用任何可想的算法,只要它总是为相同的参数返回相同的值。换句话说,如果e1 == e2,那么hash(e1) == hash(e2)也必须成立。然而,为了获得良好的性能,散列函数应该尽可能为不同的键返回不同的散列值。

对于键类型K的散列函数可能有两种提供方式。

第一种方式是通过在K的命名空间中提供一个qHash()的重载。该qHash()函数必须具有以下签名之一

size_t qHash(K key, size_t seed);
size_t qHash(const K &key, size_t seed);

size_t qHash(K key);        // deprecated, do not use
size_t qHash(const K &key); // deprecated, do not use

两个参数重载接收一个无符号整数,用于初始化散列函数的计算。该种子由QHash提供,以便防止一系列算法复杂度攻击

注意:在Qt 6中,可以定义仅接受一个参数的qHash()重载;对此的支持已被弃用。从Qt 7开始,将强制使用两个参数的重载。如果为键类型定义了一个单参数和一个双参数重载,则QHash使用后者(请注意,您可以为种子参数提供一个默认值,只是简单地定义一个双参数版本)。

提供散列函数的第二种方式是专门化针对键类型Kstd::hash类,并为此提供一个合适的功能调用运算符

namespace std {
template <> struct hash<K>
{
    // seed is optional
    size_t operator()(const K &key, size_t seed = 0) const;
};
}

种子参数的含义与qHash()相同,可以省略。

这种方式允许在QHash和C++标准库无序关联容器之间重用相同的散列函数。如果为类型同时提供了qHash()重载和std::hash特殊化,则首选qHash()重载。

以下是一些可以作为QHash键使用C++和Qt类型的部分列表:任何整型(char,unsigned long等),任何指针类型,QCharQString,以及QByteArray。对于所有这些,<QHash>头文件定义了一个用于计算适当散列值的qHash()函数。许多其他Qt类也为其类型声明了qHash重载;请参阅每个类的文档。

如果您想使用其他类型作为键,请确保您提供了operator==()和一个哈希实现。

便捷的qHashMulti()函数可以用来为自定义类型实现qHash(),在这种情况下,通常希望从多个字段生成哈希值。

示例

#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)
{
    return e1.name() == e2.name()
           && e1.dateOfBirth() == e2.dateOfBirth();
}

inline size_t qHash(const Employee &key, size_t seed)
{
    return qHashMulti(seed, key.name(), key.dateOfBirth());
}

#endif // EMPLOYEE_H

在上面的示例中,我们依赖于Qt对qHash()的自身实现,以给出员工姓名和出生日期的QStringQDate的哈希值。

请注意,Qt提供的qHash()重载实现可能会随时更改。请不要依赖于qHash()在具有不同Qt版本的情况下给出相同的结果(对于相同的输入)。

算法复杂度攻击

所有哈希表都易受到一种特定的拒绝服务攻击的攻击,其中攻击者仔细预计算了一组不同的将被哈希到哈希表相同桶中的键(或者在具有完全相同的哈希值)。此攻击的目的是在将数据放入表时获得最坏情况下的算法行为(O(n)而不是摊销O(1),有关详细信息请参阅算法复杂度)。

为了避免这种最坏情况的行为,qHash()的计算可以通过一个随机种子来加盐,从而消除攻击的严重程度。此种子由每次进程中的QHash自动生成,然后作为qHash()函数两个参数重载的第二参数传递。

默认情况下启用QHash的随机化。尽管程序不应依赖于特定的QHash顺序,但在某些情况下,您可能暂时需要确定性效果,例如调试或回归测试。要禁用随机化,将环境变量QT_HASH_SEED的定义为0。或者,您可以通过调用QHashSeed::setDeterministicGlobalSeed()函数。

另请参阅QHashIteratorQMutableHashIteratorQMapQSet

成员类型文档

QHash::ConstIterator

Qt风格的同义词QHash::const_iterator

QHash::Iterator

Qt风格的同义词QHash::iterator

QHash::const_key_value_iterator

QHash::const_key_value_iterator类型定义提供了针对QHash的STL样式const迭代器。

QHash::const_key_value_iterator基本上与QHash::const_iterator相同, difference是operator*()返回一个键/值对而不是一个值。

另请参阅QKeyValueIterator

[别名] QHash::difference_type

为ptrdiff_t提供类型别名。为STL兼容性提供。

[别名] QHash::key_type

为Key提供类型别名。为STL兼容性提供。

QHash::key_value_iterator

QHash::key_value_iterator类型定义为QHash提供了STL样式迭代器。

QHash::key_value_iterator基本上与QHash::iterator相同,差异在于operator*()返回的是一个键/值对而不是一个值。

另请参阅QKeyValueIterator

[别名] QHash::mapped_type

T的别名。为了与STL兼容而提供。

[别名] QHash::size_type

int的别名。为了与STL兼容而提供。

成员函数文档

[noexcept] T QHash::value(const Key &key) const

[noexcept] T QHash::value(const Key &key, const T &defaultValue) const

这是一个重载函数。

返回与key关联的值。

如果哈希表中没有与key关联的项,则函数返回defaultValue,或者如果没有提供此参数,则返回一个默认构造的值。

[noexcept] Key QHash::key(const T &value) const

[noexcept] Key QHash::key(const T &value, const Key &defaultKey) const

返回映射到value的第一个键。如果哈希表中没有映射到value的项,则返回defaultKey,或者如果没有提供此参数,则返回一个默认构造的键。

此函数可能很慢(线性时间),因为QHash的内部数据结构是针对快速通过键查找进行优化的,而不是通过值。

[自6.4起] auto QHash::asKeyValueRange() &

[自6.4起] auto QHash::asKeyValueRange() &&

[自6.4起] auto QHash::asKeyValueRange() const &

[自6.4起] auto QHash::asKeyValueRange() const &&

返回一个范围对象,允许以键/值对的形式迭代此哈希。例如,此范围对象可以与结构化绑定声明结合使用,用于基于范围的for循环。

QHash<QString, int> hash;
hash.insert("January", 1);
hash.insert("February", 2);
// ...
hash.insert("December", 12);

for (auto [key, value] : hash.asKeyValueRange()) {
    cout << qPrintable(key) << ": " << value << endl;
    --value; // convert to JS month indexing
}

请注意,以这种方式获取的键和值都是对哈希表中相应键和值的引用。特别是,修改值将修改哈希本身。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

此函数是在Qt 6.4中引入的。

另请参阅QKeyValueIterator

模板 <typename... Args> QHash<Key, T>::iterator QHash::emplace(Key &&key, Args &&... args)

模板 QHash<typename... Args> ::iterator QHash::emplace(const Key &key, Args &&... args)

向容器插入一个新元素。该新元素使用 args 作为构造参数就地构造。

返回指向新元素的迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

[noexcept] QHash::QHash()

构造一个空散列表。

另请参阅 clear().

QHash::QHash(std::initializer_list<std::pair<Key, T>> list)

使用初始化列表 list 中每个元素的一个副本来构造散列表。

模板 InputIterator<typename InputIterator> QHash::QHash(InputIterator begin, InputIterator end)

使用迭代器范围 [begin, end) 中每个元素的一个副本来构造散列表。该范围中迭代的元素必须是具有 firstsecond 数据成员(如 std::pair),可转换为 Key 和可转换为 T 的对象;或者迭代器必须具有 key()value() 成员函数,分别返回可转换为 Key 和可转换为 T 的键和值。

[noexcept] QHash::QHash(const QHash::Key, T> &other)

构造其他的一个副本。

由于 QHash 是 隐式共享 的,并且此操作发生在 常数时间 内,这使得从函数中返回 QHash 非常快。如果共享实例被修改,则将其复制(写时复制),这需要 线性时间

另请参阅 operator=().

[noexcept] QHash::QHash(QHash::Key, T> &&other)

移动构造一个 QHash 实例,使其指向与 other 相同的对象。

QHash::~QHash()

销毁散列表。对散列中值的引用以及该散列的所有迭代器都变为无效。

QHash<Key, T>::iterator QHash::begin()

返回指向散列表中第一个项目的 STL 样式迭代器

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅 constBegin() 和 end().

[noexcept] QHash<Key, T>::const_iterator QHash::begin() const

这是一个重载函数。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

[noexcept] qsizetype QHash::capacity() const

返回 QHash 的内部散列表中的桶的数量。

该函数的惟一目的是提供调整QHash内存使用的方法。一般来说,您很少需要调用此函数。如果想知道哈希中包含多少项,请调用size()。

另请参阅reserve()和squeeze()。

[noexcept] QHash<Key, T>::const_iterator QHash::cbegin() const

返回一个指向哈希中第一个项目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅begin()和cend()。

[noexcept] QHash<Key, T>::const_iterator QHash::cend() const

返回一个指向哈希中最后一个项目之后虚拟项目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅cbegin()和end()。

[noexcept(...)] void QHash::clear()

从哈希中删除所有项目并释放它使用的所有内存。

注意:当“std::is_nothrow_destructible<Node>::value”为真时,此函数不会抛出任何异常。

另请参阅remove()。

[noexcept] QHash<Key, T>::const_iterator QHash::constBegin() const

返回一个指向哈希中第一个项目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅begin()和constEnd()。

[noexcept] QHash<Key, T>::const_iterator QHash::constEnd() const

返回一个指向哈希中最后一个项目之后虚拟项目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅 constBegin() 和 end().

[noexcept] QHash<Key, T>::const_iterator QHash::constFind(const Key &key) const

返回一个指向哈希中具有key的项目的迭代器。

如果哈希中没有具有key的项目,则函数返回constEnd

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅find()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::constKeyValueBegin() const

返回一个指向哈希中第一个条目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyValueBegin()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::constKeyValueEnd() const

返回一个指向哈希中最后一个条目之后虚拟条目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅constKeyValueBegin()。

[noexcept] bool QHash::contains(const Key &key) const

如果哈希表包含具有 key 的项,则返回 true;否则返回 false

另请参阅count()。

[noexcept] qsizetype QHash::count(const Key &key) const

返回与 key 关联的项的数量。

另请参阅contains()。

[noexcept] qsizetype QHash::count() const

这是一个重载函数。

size() 相同。

[noexcept] bool QHash::empty() const

此函数是为 STL 兼容性提供的。它与 isEmpty() 相等,如果哈希表为空则返回 true,否则返回 false

[noexcept] QHash<Key, T>::iterator QHash::end()

返回一个指向哈希表中最后一个项后面的虚拟项的 STL 风格迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅begin()和constEnd()。

[noexcept] QHash<Key, T>::const_iterator QHash::end() const

这是一个重载函数。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

QHash<Key, T>::iterator QHash::erase(QHash<Key, T>::const_iterator pos)

从哈希表中移除与迭代器 pos 关联的 (key, value) 对,并返回指向哈希表中下一个项的迭代器。

此函数永远不会导致 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;
    }
}

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅remove()、take() 和 find()。

QHash<Key, T>::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() << endl;
    ++i;
}

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅value() 和 values()。

[noexcept] QHash<Key, T>::const_iterator QHash::find(const Key &key) const

这是一个重载函数。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

QHash<Key, T>::iterator QHash::insert(const Key &key, const T &value)

使用 和值为 value 添加新项。

如果已存在具有 的项,则该项的值将用 value 替换。

返回指向新/更新元素的迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

void QHash::insert(const QHash<Key, T> &other)

other 中所有项插入到该哈希中。

如果键在两个哈希中都有,则其值将用 other 中存储的值替换。

[noexcept] bool QHash::isEmpty() const

若哈希中不包含任何项,则返回 true;否则返回 false

另请参阅size

[noexcept] QHash<Key, T>::key_iterator QHash::keyBegin() const

返回一个指向哈希中第一个键的常量 STL-style 迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyEnd

[noexcept] QHash<Key, T>::key_iterator QHash::keyEnd() const

返回一个指向哈希中最后一个键之后的假设项目的常量 STL-style 迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyBegin

QHash<Key, T>::key_value_iterator QHash::keyValueBegin()

返回指向哈希中第一个条目的 STL-style 迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyValueEnd

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::keyValueBegin() const

返回一个指向哈希中第一个条目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyValueEnd

QHash<Key, T>::key_value_iterator QHash::keyValueEnd()

返回指向哈希中最后一个条目之后的假设条目的 STL-style 迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyValueBegin()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::keyValueEnd() const

返回一个指向哈希中最后一个条目之后虚拟条目的常量STL-style迭代器。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

另请参阅keyValueBegin()。

QList<Key> QHash::keys() const

返回一个包含哈希中所有键的列表,顺序任意。

顺序 guaranteed to 与 values() 中使用的顺序相同。

此函数以线性时间创建新列表。可以通过从 keyBegin() 迭代到 keyEnd() 来避免因此而产生的时空消耗。

另请参阅values() 和 key

QList<Key> QHash::keys(const T &value) const

这是一个重载函数。

返回一个包含与值 value 相关的所有键的列表,顺序任意。

此函数可能很慢(线性时间),因为QHash的内部数据结构是针对快速通过键查找进行优化的,而不是通过值。

[noexcept] float QHash::load_factor() const

返回 QHash 内部哈希表当前的负载因子。这与 capacity()/size(). 相同。使用的实现将努力将负载因子保持在 0.25 到 0.5 之间。这样可以避免过多的哈希表冲突,从而降低性能。

即使在负载因子较低的情况下,哈希表的实现也有非常低的内存开销。

此方法仅出于诊断目的,您很少需要自己调用它。

另请参阅reserve()和squeeze()。

bool QHash::remove(const Key &key)

从哈希表中移除具有 key 的项目。如果键存在于哈希表中并且已经移除,则返回 true,否则返回 false。

另请参阅clear() 和 take().

[since 6.1] template <typename Predicate> qsizetype QHash::removeIf(Predicate pred)

从哈希表中移除所有使谓词 pred 返回 true 的元素。

该函数支持接收参数为 QHash<Key, T>::iteratorstd::pair<const Key &, T &> 类型的谓词。

如果移除了元素,则返回移除的元素数量。

此功能是自 Qt 6.1 引入的。

另请参阅clear() 和 take().

void QHash::reserve(qsizetype size)

确保 QHash 的内部哈希表有足够的空间存储至少 size 项,而无需扩展哈希表。

这意味着哈希表将包含至少 2 * size 个桶,以确保良好的性能。

此函数对于需要构建大型哈希表且希望避免重复分配的代码很有用。例如

QHash<QString, int> hash;
hash.reserve(20000);
for (int i = 0; i < 20000; ++i)
    hash.insert(keys[i], values[i]);

理想情况下,size 应该是哈希表中预期项目的最大数量。然后 QHash 将选择允许在表中存储 size 项的最小桶数。如果 size 是低估的,最坏的情况是 QHash 将变得稍微慢一些。

通常情况下,您很少需要调用此函数。 QHash 的内部哈希表会自动扩展以提供良好的性能而不浪费太多内存。

另请参阅squeeze() 和 capacity().

[noexcept] qsizetype QHash::size() const

返回哈希表中的项目数量。

另请参阅isEmpty() 和 count().

void QHash::squeeze()

QHash 内部哈希表的大小减少以节省内存。

此函数的唯一目的是提供一种调整 QHash 内存使用的方式。通常,您很少需要调用此函数。

另请参阅reserve() 和 capacity

[noexcept] void QHash::swap(QHash<Key, T> &other)

交换此哈希与其它哈希 other。此操作非常快且永远不会失败。

T QHash::take(const Key &key)

从哈希中删除具有 key 的项并返回与其关联的值。

如果项不在哈希中,则函数仅返回一个 默认构造的值

如果您不使用返回值,则 remove() 更有效率。

另请参阅remove()。

QList<T> QHash::values() const

返回包含哈希中所有值的列表,顺序任意。

顺序保证与 keys() 使用的一致。

此函数以 线性时间 创建一个新的列表。可以通过从 keyValueBegin() 迭代到 keyValueEnd() 避免由此产生的时间和内存使用。

另请参阅keys() 和 value

bool QHash::operator!=(const QHash<Key, T> &other) const

如果 other 不等于此哈希,则返回 true;否则返回 false

如果两个哈希包含相同的(键,值)对,则认为它们是相等的。

此函数要求值类型实现 operator==()

另请参阅operator==

[noexcept(...)] QHash<Key, T> &QHash::operator=(const QHash<Key, T> &other)

other 赋值给此哈希并返回对此哈希的引用。

注意:当“std::is_nothrow_destructible<Node>::value”为真时,此函数不会抛出任何异常。

[noexcept] QHash<Key, T> &QHash::operator=(QHash<Key, T> &&other)

移动赋值 other 到此 QHash 实例。

bool QHash::operator==(const QHash<Key, T> &other) const

如果 other 等于此哈希,则返回 true;否则返回 false。

如果两个哈希包含相同的(键,值)对,则认为它们是相等的。

此函数要求值类型实现 operator==()

另请参阅operator!=

T &QHash::operator[](const Key &key)

返回与 key 关联的值,作为一个可修改的引用。

如果哈希中不包含具有 key 的项目,则函数会将默认构造的值插入到哈希表中,并将该值与 key 关联,并返回对该值的引用。

警告:在下次调用非const函数或哈希被销毁时,返回的迭代器/引用将应被视为已失效。

也见 insert() 和 value

[noexcept] const T QHash::operator[](const Key &key) const

这是一个重载函数。

value 相同。

相关非成员

[since 6.1] template <typename Key, typename T, typename Predicate> qsizetype erase_if(QHash<Key, T> &hash, Predicate pred)

从哈希中删除所有由谓词 pred 返回 true 的元素。

该函数支持接收参数为 QHash<Key, T>::iteratorstd::pair<const Key &, T &> 类型的谓词。

如果移除了元素,则返回移除的元素数量。

此功能是自 Qt 6.1 引入的。

[noexcept] size_t qHash(const QUrl &url, size_t seed = 0)

返回 url 的哈希值。如果指定,则使用 seed 来初始化哈希。

[noexcept(...)] template <typename Key, typename T> size_t qHash(const QHash<Key, T> &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

类型 T 必须由 qHash() 支持。

注意: 当 "noexcept(qHash(std::declval<Key&>())) && noexcept(qHash(std::declval<T&>()))" 为真时,这个函数不会抛出任何异常。

[noexcept, since 6.0] size_t qHash(QPoint key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

[noexcept(...)] template <typename T> size_t qHash(const QSet<T> &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

哈希值独立于 key 元素的顺序,即包含相同元素的集合哈希到相同的值。

注意: 当 "noexcept(qHashRangeCommutative(key.begin(), key.end(), seed))" 为真时,此函数不会抛出任何异常。

[since 6.0] size_t qHash(const QTypeRevision &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

size_t qHash(const QVersionNumber &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

size_t qHash(const QDateTime &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(QDate key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] 类型为 size_tqHash 函数(QTime key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept(...)] 模板函数 size_t 类型,参数为 std::pair<T1, T2> &的 qHash 函数常量模板(size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

T1T2 的类型必须由 qHash() 支持。

注意: 当 "QHashPrivate::noexceptPairHash<T1, T2>()" 为真时,此函数不会抛出任何异常。

[constexpr noexcept] 类型为 size_tqHash 函数(char key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(uchar key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(signed char key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(ushort key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(short key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(uint key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(int key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(ulong key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(long key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(quint64 key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] 类型为 size_tqHash 函数(qint64 key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept, since 6.0] 类型为 size_tqHash 函数(char8_t key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

[constexpr noexcept, since 6.0] 类型为 size_tqHash 函数(char16_t key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

[constexpr noexcept, since 6.0] size_t qHash(char32_t key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

[constexpr noexcept, since 6.0] size_t qHash(wchar_t key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

[noexcept] size_t qHash(float key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(double key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(long double key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept] size_t qHash(const QChar key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(const QByteArray &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(const QBitArray &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(const QString &key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] size_t qHash(QLatin1StringView key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[noexcept] template <typename T> size_t qHash(const T *key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

[constexpr noexcept, since 6.0] size_t qHash(std::nullptr_t key, size_t seed = 0)

返回 key 的哈希值,使用 seed 来初始化计算。

此函数是在 Qt 6.0 中引入的。

[noexcept] size_t qHashBits(const void *p, size_t len, size_t seed = 0)

返回由指针 p 指向的长度为 len 的内存块的哈希值,使用 seed 作为计算的种子。

请仅使用此函数为您自己的自定义类型实现 qHash()。例如,这里是如何为 std::vector<int> 实现一个 qHash()重载的:

inline size_t qHash(const std::vector<int> &key, size_t seed = 0)
{
    if (key.empty())
        return seed;
    else
        return qHashBits(&key.front(), key.size() * sizeof(int), seed);
}

这利用了 std::vector 以连续方式排列其数据的特性。如果这不是这种情况,或者包含的类型具有填充,则应使用 qHashRange()。

重复强调,qHashBits() 的实现 - 如 Qt 提供的 qHash() 重载 - 可能随时更改。你必须不得依赖 qHashBits() 在不同 Qt 版本中给出相同结果(对于相同的输入)。

另请参阅 qHashRange() 和 qHashRangeCommutative().

[constexpr noexcept(...), since 6.0] 模板 <typename... T> size_t qHashMulti(size_t seed, const T &... args)

返回对 args 的哈希值,使用 seed 作为计算种子,通过逐个应用 qHash() 到每个元素并将哈希值组合成一个单一的值。

请注意参数的顺序很重要。如果顺序无关紧要,请使用 qHashMultiCommutative()。如果你正在哈希原始内存,请使用 qHashBits();如果你正在哈希一个范围,请使用 qHashRange().

此函数提供作为便利,来自定义类型实现 qHash()。例如,以下是如何为 qHash() 实现一个类的重载的方法 Employee

#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)
{
    return e1.name() == e2.name()
           && e1.dateOfBirth() == e2.dateOfBirth();
}

inline size_t qHash(const Employee &key, size_t seed)
{
    return qHashMulti(seed, key.name(), key.dateOfBirth());
}

#endif // EMPLOYEE_H

此函数是在 Qt 6.0 中引入的。

注意: 当 "std::conjunction_v<QtPrivate::QNothrowHashable<T>...>" 为 true 时,此函数不会抛出任何异常。

另请参阅 qHashMultiCommutativeqHashRange.

[constexpr noexcept(...), since 6.0] 模板 <typename... T> size_t qHashMultiCommutative(size_t seed, const T &... args)

返回对 args 的哈希值,使用 seed 作为计算种子,通过逐个应用 qHash() 到每个元素并将哈希值组合成一个单一的值。

参数的顺序无关紧要。如果顺序很重要,请使用 qHashMulti(),因为它可能产生更好的哈希质量。如果你正在哈希原始内存,请使用 qHashBits();如果你正在哈希一个范围,请使用 qHashRange().

此函数提供作为便利,来自定义类型实现 qHash().

此函数是在 Qt 6.0 中引入的。

注意: 当 "std::conjunction_v<QtPrivate::QNothrowHashable<T>...>" 为 true 时,此函数不会抛出任何异常。

另请参阅 qHashMultiqHashRange.

[noexcept(...)] 模板 <typename InputIterator> size_t qHashRange(InputIterator first, InputIterator last, size_t seed = 0)

返回范围 [first,last) 的哈希值,使用 seed 作为计算种子,通过逐个应用 qHash() 到每个元素并将哈希值组合成一个单一的值。

此函数的返回值取决于范围中元素的顺序。这意味着

{0, 1, 2}

{1, 2, 0}

将具有不同的值。如果顺序无关紧要,例如对于哈希表,请改用 qHashRangeCommutative()。如果你正在哈希原始内存,请使用 qHashBits().

请仅使用此函数为您自己的自定义类型实现 qHash()。例如,这里是如何为 std::vector<int> 实现一个 qHash()重载的:

inline size_t qHash(const std::vector<int> &key, size_t seed = 0)
{
    return qHashRange(key.begin(), key.end(), seed);
}

重复强调,qHashRange() 的实现 - 如 Qt 提供的 qHash() 重载 - 可能随时更改。你不得依赖于 qHashRange() 将给出相同结果(对于相同的输入)的事实,即使在元素类型上的 qHash() 就会是这样。

注意: 当 noexcept(qHash(*first)) 为 true 时,此函数不会抛出任何异常。

另请参阅 qHashBits() 和 qHashRangeCommutative().

[noexcept(...)] 模板 <typename InputIterator> size_t qHashRangeCommutative(InputIterator first, InputIterator last, size_t seed = 0)

返回范围 [first,last) 的哈希值,使用 seed 作为计算种子,通过逐个应用 qHash() 到每个元素并将哈希值组合成一个单一的值。

此函数的返回值不依赖于范围内元素顺序。这意味着

{0, 1, 2}

{1, 2, 0}

计算相同值。如果顺序很重要,例如对于vector和数组,请使用 qHashRange()。如果您正在哈希原始内存,请使用 qHashBits()。

仅使用此函数来实现您自定义类型的 qHash()。例如,以下是如何为 std::unordered_set<int> 实现一个 qHash() 覆盖。

inline size_t qHash(const std::unordered_set<int> &key, size_t seed = 0)
{
    return qHashRangeCommutative(key.begin(), key.end(), seed);
}

需要重申的是,qHashRangeCommutative() 的实现(就像 Qt 提供的 qHash() 覆盖)可能会随时更改。您 绝不应 依赖 qHashRangeCommutative() 在不同 Qt 版本中给出相同的(对于相同的输入)结果,即使 qHash() 对于元素类型会如此。

注意: 当 noexcept(qHash(*first)) 为 true 时,此函数不会抛出任何异常。

另请参阅 qHashBits() 和 qHashRange()。

模板 <typename Key, typename T> QDataStream &operator<<(QDataStream &out, const QHash<Key, T> &hash)

将哈希 hash 写入到流 out

此函数要求键和值类型实现 operator<<()

另请参阅 序列化 Qt 数据类型

模板 <typename Key, typename T> QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash)

从流 in 读取哈希到 hash

此函数要求键和值类型实现 operator>>()

另请参阅 序列化 Qt 数据类型

© 2024 Qt 公司 Ltd. 本文档中包含的文档贡献是各自所有者的版权。本文档是根据自由软件基金会发布并由其许可的GNU自由文档许可协议版本1.3提供的。Qt 和相关标志是芬兰和/或世界其他地区的Qt公司 Ltd 的商标。所有其他商标均为其各自所有者的财产。