QHash <Key,T>是Qt的通用容器类之一。它存储(键,值)对,并提供与键关联的值的快速查找。
1,QHash提供与QMap非常相似的功能。

不同之处在于:

(1)QHash提供比QMap更快的查找,但所需空间更大。

(2)QMap默认按照键值升序排序;。使用QHash按照键值任意排序。

(3)QMap的键类型必须提供operator <()。QHash的键类型必须提供operator ==()和称为qHash()的全局哈希函数。

2,一个QHash每个键只允许一个值。

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

3,如果只需要从哈希中提取值(而不是键),则也可以使用foreach:

    QHash<QString, int> hash;...foreach (int value, hash)cout << value << Qt::endl;

Qt进入foreach循环时会自动获取容器的副本,如果在迭代时修改容器,则不会影响循环(如果不修改容器,则仍会进行复制,但是由于隐式共享,复制容器非常快)。由于foreach会创建容器的副本,因此对变量使用非常量引用将不允许您修改原始容器,它只会影响副本。

Qt foreach循环的替代方法for是C ++ 11和更高版本中的基于范围的。但是,基于范围的for可能会强制Qt容器分离,而foreach不会。使用foreachAlways复制容器,对于STL容器通常并不容易。建议使用foreach Qt容器,并使用基于范围的forSTL 容器。
4,qHash()函数

QHash的键类型除了是可分配的数据类型外,还具有其他要求:它必须提供operator ==(),并且该类型的名称空间中还必须有一个qHash()函数,该函数返回键类型的参数的哈希值。该qHash()函数计算基于密钥的数值。只要给定相同的参数,它总是返回相同的值,它就可以使用任何可以想象的算法。换句话说,如果e1 == e2,则qHash(e1) == qHash(e2)也必须成立。但是,为了获得良好的性能,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

注意:如果是自定义类型或是第三方库类型作为哈希表的键值时,对perator ==()和qHash()函数的定义必须是全局的,要定义在使用QHash<K,T>之前,如果有命名空间,则是定义在命名空间之外的,否则qt模板函数是无法通过自定义模板::类名::qHash来调用自定义的哈希函数,会出现如下错误:

error C2665: “qHash”: 25 个重载中没有一个可以转换所有参数类型   
 5,QHash实现的键值哈希函数

Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW;Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW{return (sizeof(ulong) > sizeof(uint))? (uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed) : (uint(key & (~0U)) ^ seed);}
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); }
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW{ return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed;}
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
#ifndef Q_OS_DARWIN
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
#endif
Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QString &key) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW;template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
{return qHash(reinterpret_cast<quintptr>(key), seed);
}
template<typename T> inline uint qHash(const T &t, uint seed)Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
{ return (qHash(t) ^ seed); }template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key, uint seed = 0)Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed)))
{uint h1 = qHash(key.first, seed);uint h2 = qHash(key.second, seed);return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed;
}

qHash中关于处理指针键值的哈希函数,如下:

Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW;

template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
{
    return qHash(reinterpret_cast<quintptr>(key), seed);
}

指针哈希函数应用如下:(其中handle为第三方库智能指针,1、3例指针转int可能会溢出)

    inline uint qHash(const Handle(AIS_Shape)& key){return qHash(reinterpret_cast<quintptr>(key.get()));//return qHashBits(key.get(), sizeof(AIS_Shape*), 0);//return qHash((int)key.get());}

6,Qt关联容器和集合的算法复杂性:

使用QVector,QHash和QSet,附加项的性能摊销为O(log n)。在插入项目之前,可以通过调用QVector :: reserve(),QHash :: reserve()(或QSet :: reserve()并使用预期的项目数将其降至O(1)。

原文链接:https://blog.csdn.net/qq_43405330/article/details/108028980

QT之QHash简介相关推荐

  1. [Qt教程] 第21篇 数据库(一)Qt数据库应用简介

    [Qt教程] 第21篇 数据库(一)Qt数据库应用简介 楼主  发表于 2013-5-13 20:56:39 | 查看: 1403| 回复: 13 Qt数据库应用简介 版权声明 该文章原创于作者yaf ...

  2. [Qt教程] 第31篇 网络(一)Qt网络编程简介

    [Qt教程] 第31篇 网络(一)Qt网络编程简介 楼主  发表于 2013-8-28 17:04:17 | 查看: 515| 回复: 0 Qt网络编程简介 版权声明 该文章原创于作者yafeilin ...

  3. Qt Quick 3D简介

    Qt Quick 3D简介 前言 Qt Quick 3D是Qt自带的一套3D图形系统,与传统的Qt 3D不同的是,Qt Quick 3D采用QML来进行开发.本节则对Qt Quick 3D进行一次简单 ...

  4. QT的QHash类的使用

    详细说明 QHash类是提供基于散列表的字典的模板类. QHash <Key,T>是Qt的通用容器类之一.它存储(键,值)对,并提供与键关联的值的快速查找. QHash提供与QMap非常相 ...

  5. 【Qt】Qt中JSON简介

    00. 目录 文章目录 00. 目录 01. JSON简介 02. JSON Support in Qt 03. JSON类 04. 附录 01. JSON简介 1.1 JSON概述 JSON(Jav ...

  6. 【QT】QObject简介

    1.简介 QObject类是所有Qt对象的基类,是Qt对象模型的核心,这个模型的主要特征为信号与槽,信号与槽是一个非常重要的机制,用于对象间的通信.连接信号与槽使用connect()函数,断开连接使用 ...

  7. QT——开发入门简介

    [系列专栏]:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! <QT开发实战> <嵌入式通用开发实战> <嵌入式Linux开发实战> 1.你了解Qt吗? ...

  8. 【Qt炫酷动画】0.Qt动画类简介

    动画类继承关系 #mermaid-svg-ghWzAqD79vPW4ai1 {font-family:"trebuchet ms",verdana,arial,sans-serif ...

  9. Qt IFW框架简介

    概述 Qt IFW,全称Qt Install Framework,这是Qt官方提供的一套实用工具,用于为Qt桌面平台(Linux,Windows和OS X)创建安装程序.官网介绍. 软件打包工具其实有 ...

最新文章

  1. Linux批量文件名大小写转换,Linux中批量把目录内文件名转换大小写用tr
  2. Cobbler部署指南之Cobbler安装操作系统篇
  3. php内置邮件sendmail发送,PHP发送邮件函数sendmail()
  4. 计算机专业的大学生自我介绍,计算机专业大学生自我介绍
  5. Barracuda VS antelope
  6. 【算法竞赛学习】二手车交易价格预测-Task1赛题理解
  7. SpringBoot控制层页面指定返回html前端页面
  8. MVC进阶学习--HtmlHelper控件解析(五)
  9. 数据的经济活动及其所需要的权利
  10. 2022届软件技术专业毕业生就业岗位分析(.Net方向)
  11. 【RL系列】马尔可夫决策过程——Gambler's Problem
  12. 案例:世界500强如何打造汽车后市场智慧门店
  13. 计算机网络(五):IPv6
  14. 微信的根服务器在哪国,为何很多人把微信上的国家设置成安道尔?安道尔在哪里?...
  15. scratch字母点头问好 电子学会图形化编程scratch等级考试一级真题和答案2020-9
  16. python bins分箱,划分数值区间
  17. cocosCreator 用进度条展示场景加载进度
  18. 安装MySQL时cmake包的依赖问题
  19. Go 如何使用session
  20. 手游服务端框架之自定义orm持久化工具

热门文章

  1. CADENCE ORCAD原理图导出FPGA UCF的方法
  2. android点击弹出日期选择器,关于Android 点击按钮弹出日期选择器
  3. 流量回放开源代码Java_流量回放框架 jvm-sandbox-repeater 的实践
  4. java中负数取整_Java取整,固定保留两位小数,适配负数、金融数字。
  5. java 更新jlabel_java - 用Java更新绑定的JLabel文本 - 堆栈内存溢出
  6. PHP-02.文件上传、php保存/转移上传的文件、常见的网络传输协议、请求报文及属性、响应报文及属性...
  7. ELASTIC API
  8. LeetCode Search Insert Position (二分查找)
  9. 指向类的数据成员和函数指针
  10. android doc例程---Notepad Tutorial学习要点!