当前位置: 首页 > news >正文

Qt Essential Classes

目录

QVariant

QFlags

QRandomGenerator

经典的Qt容器

QVector

QList

QMap

QMultiMap

QSet

QHash


QVariant

同std::variant是一样的,他是一个更加高级的union。在一个时间下,它虽然实际上只能是一种类型,但是一个variant可以hold住所有的types(因为本质上都是内存块塞0和1,理解这一点的同志们直接看API就完事了),这样,我们直接就可以存储一个通用的类型,对于不同的场景做对应的转换就好了!我的另一个意思是:提供了一个统一的接口来处理各种数据类型。QVariant 可以存储简单的数据类型(如整型、浮点型、字符串等)以及复杂的数据类型(如自定义类、列表等)。

方法描述
QVariant()默认构造函数,创建一个无效的 QVariant。
QVariant(const QVariant &other)拷贝构造函数。
QVariant(QVariant &&other)移动构造函数。
QVariant &operator=(const QVariant &other)赋值操作符。
QVariant &operator=(QVariant &&other)移动赋值操作符。
bool isValid() const检查 QVariant 是否有效。
bool isNull() const检查 QVariant 是否为空。
int type() const返回存储数据的类型。
QString typeName() const返回存储数据类型的名称。
template<typename T>T value():将 QVariant 转换为指定类型。
void clear()清除存储的数据。
static QVariant fromValue(const T &value)从值创建 QVariant。
template<typename T>static T fromVariant(const QVariant &variant):从 QVariant 获取值。
QVariantList toList() const将 QVariant 转换为 QVariantList(如有必要)。
QVariantMap toMap() const将 QVariant 转换为 QVariantMap(如有必要)。

试一手:

#include <QVariant>
#include <QString>
#include <QDebug>
​
int main() {QVariant variant;
​// 存储整数variant = 42;qDebug() << "Stored integer:" << variant.toInt();
​// 存储字符串variant = QString("Hello, QVariant!");qDebug() << "Stored string:" << variant.toString();
​// 检查类型if (variant.type() == QVariant::String) {qDebug() << "Variant holds a string.";}
​// 使用 fromValue 和 toVariantQVariant doubleVariant = QVariant::fromValue(3.14);double value = doubleVariant.value<double>();qDebug() << "Stored double:" << value;
​return 0;
}

QFlags

这个笔者感悟比较深:他在你设置一些对象的属性的时候很管用:它通过位运算提供了一种简单而高效的方式来组合多个标志。QFlags 主要用于处理枚举类型的标志组合,使得代码更加清晰和易于维护。

笔者建议你按照std::bitset的一个高级抽象来理解。我们实际上就是使用比特表达信息!完事!

方法描述
QFlags()默认构造函数,创建一个无效的 QFlags 对象。
QFlags(Flags f)构造函数,使用给定的标志初始化 QFlags 对象。
QFlags(const QFlags &other)拷贝构造函数。
QFlags(QFlags &&other)移动构造函数。
QFlags &operator=(const QFlags &other)赋值操作符。
QFlags &operator=(QFlags &&other)移动赋值操作符。
QFlags operator|(const QFlags &other) const或操作符,用于实现位或操作符,允许将两个 QFlags 对象的标志组合在一起。这个操作符返回一个新的 QFlags 对象,包含了两个原对象的所有标志。
QFlags operator&(const QFlags &other) const位与操作符,用于获取共同标志。
QFlags operator^(const QFlags &other) const位异或操作符,用于获取不共同的标志。
QFlags operator~() const位非操作符,反转当前标志。
bool testFlag(Flags f) const测试特定标志是否被设置。
QFlags& operator|=(const QFlags &other)赋值操作
QFlags& operator&=(const QFlags &other)复合位与赋值操作符。
QFlags& operator^=(const QFlags &other)复合位异或赋值操作符。
static QFlags fromValue(int value)从整数值创建 QFlags 对象。
#include <QCoreApplication>
#include <QFlags>
#include <QDebug>
​
enum MyFlags {FlagA = 0x1, // 0001FlagB = 0x2, // 0010FlagC = 0x4  // 0100
};
​
Q_DECLARE_FLAGS(MyFlagSet, MyFlags)
​
int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);
​// 创建标志MyFlagSet flags;flags |= FlagA;  // 添加 FlagAflags |= FlagB;  // 添加 FlagB
​// 检查标志if (flags.testFlag(FlagA)) {qDebug() << "FlagA is set.";}
​if (flags.testFlag(FlagB)) {qDebug() << "FlagB is set.";}
​// 组合标志MyFlagSet moreFlags = FlagB | FlagC; // 组合 FlagB 和 FlagCflags |= moreFlags; // 添加组合的标志
​// 输出当前标志状态qDebug() << "Current flags:" << flags;
​// 测试 FlagC 是否被设置if (flags.testFlag(FlagC)) {qDebug() << "FlagC is set.";}
​// 使用位与操作获取共同标志MyFlagSet commonFlags = flags & moreFlags;qDebug() << "Common flags:" << commonFlags;
​return a.exec();
}
​
Q_DECLARE_METATYPE(MyFlagSet)

QRandomGenerator

这个玩意是检验你是Qt6选手还是Qt5选手的标准类。他就是qt5的qrand()的高级版,提供了一系列方法来生成均匀分布和正态分布的随机数,支持多种数据类型。QRandomGenerator 是线程安全的,因此可以在多线程环境中安全使用。

  • 性能:高效生成随机数,适合需要大量随机数的应用场景。

  • 可移植性:在不同平台上具有一致的行为。

  • 种子控制:支持通过种子初始化生成器,以便于生成可重复的随机数序列。

  • 随机数分布:支持生成均匀分布、正态分布等类型的随机数。

方法描述
QRandomGenerator()默认构造函数,使用当前时间作为种子。
QRandomGenerator(uint seed)使用指定种子初始化生成器。
static QRandomGenerator *global()返回全局的随机数生成器实例。
int bounded(int range)生成一个在 [0, range) 范围内的随机整数。
double generateDouble()生成一个在 [0.0, 1.0) 范围内的随机浮点数。
int generateInt()生成一个随机整数。
void seed(uint seed)设置生成器的种子。
static void globalSeed(uint seed)设置全局随机数生成器的种子。
#include <QCoreApplication>
#include <QRandomGenerator>
#include <QDebug>
​
int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);
​// 创建一个 QRandomGenerator 实例QRandomGenerator *generator = QRandomGenerator::global();
​// 生成 10 个随机整数qDebug() << "Random integers:";for (int i = 0; i < 10; ++i) {int randomInt = generator->bounded(100); // 在 [0, 100) 范围内qDebug() << randomInt;}
​// 生成 10 个随机浮点数qDebug() << "Random doubles:";for (int i = 0; i < 10; ++i) {double randomDouble = generator->generateDouble(); // 在 [0.0, 1.0) 范围内qDebug() << randomDouble;}
​return a.exec();
}

经典的Qt容器

QVector

QVector 是 Qt 提供的一种动态数组容器,类似于 C++ 标准库中的 std::vector。它用于存储同一类型的元素,并支持快速的随机访问、插入和删除操作。QVector 主要用于需要动态调整大小且频繁读取元素的场景。

是的,就是std::vector的Qt版本。笔者在《Qt高性能编程》中见到过观点:use std rather than qt,这个事情仁者见仁智者见智。笔者认为按照场景使用最好。

  • 动态大小QVector 可以根据需要自动扩展或收缩。

  • 快速随机访问:可以通过索引快速访问元素,访问时间复杂度为 O(1)。

  • 连续内存存储:数据在内存中是连续存储的,能更好地利用 CPU 缓存,提高性能。

  • 支持多种数据类型:可以存储任意类型的数据,通常与 Qt 的其他类型(如 QVariant)结合使用。

  • 高效的内存管理:通过智能的内存分配策略减少内存碎片。

方法描述
QVector<T>()默认构造函数,创建一个空的 QVector
QVector<T>(int size)创建一个指定大小的 QVector,元素初始化为 T()
QVector<T>(const QVector<T> &other)拷贝构造函数,复制另一个 QVector 的内容。
~QVector()析构函数,释放内存。
T& operator[](int index)返回指定索引处的元素的引用。
const T& operator[](int index) const返回指定索引处的元素的常量引用。
int size() const返回当前元素的数量。
bool isEmpty() const判断 QVector 是否为空。
void append(const T &value)QVector 末尾添加一个新元素。
void prepend(const T &value)QVector 开头添加一个新元素。
void insert(int index, const T &value)在指定位置插入一个新元素。
void removeAt(int index)移除指定位置的元素。
void clear()清空 QVector 中的所有元素。
T takeAt(int index)移除并返回指定位置的元素。
void resize(int size)调整 QVector 的大小,增加或减少元素数量。
T& first()返回第一个元素的引用。
T& last()返回最后一个元素的引用。
QVector<T> mid(int pos, int length = -1) const返回从 pos 开始的子数组。
QVector<T> &operator=(const QVector<T> &other)赋值运算符,复制另一个 QVector 的内容。
bool operator==(const QVector<T> &other) const判断两个 QVector 是否相等。
#include <QVector>
#include <QDebug>
​
int main() {// 创建一个空的 QVectorQVector<int> vec;
​// 添加元素vec.append(10);vec.append(20);vec.append(30);// 输出当前大小qDebug() << "Size:" << vec.size(); // Size: 3
​// 访问元素qDebug() << "First element:" << vec.first(); // First element: 10
​// 插入元素vec.insert(1, 15);// 输出元素for (int i = 0; i < vec.size(); ++i) {qDebug() << vec[i]; // 10 15 20 30}
​// 移除元素vec.removeAt(2); // 移除元素 20
​// 清空 QVectorvec.clear();// 检查是否为空qDebug() << "Is empty:" << vec.isEmpty(); // Is empty: true
​return 0;
}

它的数据结构特点:

  • 访问速度:因为数据是连续存储的,所以 QVector 的访问速度通常比链表等非连续存储的数据结构快。

  • 插入和删除:虽然在末尾插入和删除操作的时间复杂度为 O(1),但在中间位置插入和删除的时间复杂度为 O(n),这要注意。

它的常见的使用场景:

  • 动态数据集合:当需要一个大小可变的数组来存储数据时,例如用户输入、实时数据流等。

  • 临时存储:处理算法时使用的临时数据,例如排序、搜索等。

  • 图形界面:在 Qt 应用中,常用于存储 UI 组件、图形对象等。

QList

注意在Qt6下,QList == QVector,这里是给Qt5看的:

QList实际上更加的智能,这点随了Java的List:原生类型存数值,复杂类型存指针。但是注意,QList仍然是连续的。比起来,QLinkedList确实是真正的链表!这点请所有使用链表的客户程序员注意!使用链表是QLinkedList!

QList<T>()默认构造函数,创建一个空的 QList
QList<T>(int size)创建一个指定大小的 QList,元素初始化为 T()
QList<T>(const QList<T> &other)拷贝构造函数,复制另一个 QList 的内容。
~QList()析构函数,释放内存。
T& operator[](int index)返回指定索引处的元素的引用。
const T& operator[](int index) const返回指定索引处的元素的常量引用。
int size() const返回当前元素的数量。
bool isEmpty() const判断 QList 是否为空。
void append(const T &value)QList 末尾添加一个新元素。
void prepend(const T &value)QList 开头添加一个新元素。
void insert(int index, const T &value)在指定位置插入一个新元素。
void removeAt(int index)移除指定位置的元素。
void clear()清空 QList 中的所有元素。
T takeAt(int index)移除并返回指定位置的元素。
T& first()返回第一个元素的引用。
T& last()返回最后一个元素的引用。
QList<T> mid(int pos, int length = -1) const返回从 pos 开始的子列表。
QList<T> &operator=(const QList<T> &other)赋值运算符,复制另一个 QList 的内容。
bool operator==(const QList<T> &other) const判断两个 QList 是否相等。
#include <QList>
#include <QDebug>
​
int main() {// 创建一个空的 QListQList<int> list;
​// 添加元素list.append(10);list.append(20);list.append(30);
​// 输出当前大小qDebug() << "Size:" << list.size(); // Size: 3
​// 访问元素qDebug() << "First element:" << list.first(); // First element: 10
​// 插入元素list.insert(1, 15);// 输出元素for (int i = 0; i < list.size(); ++i) {qDebug() << list[i]; // 10 15 20 30}
​// 移除元素list.removeAt(2); // 移除元素

QMap

QMap 是 Qt 提供的一种基于红黑树的关联容器,主要用于存储键值对。它类似于 C++ 标准库中的 std::map,但在使用上更加方便,特别是在与 Qt 其他类的结合使用时。QMap 提供了快速的查找、插入和删除操作,同时能够保持键的有序性。

  • 有序性QMap 中的键是自动排序的,因此可以根据键的顺序遍历元素。

  • 快速查找:使用红黑树实现,查找、插入和删除的平均时间复杂度为 O(log n)。

  • 多类型支持:可以存储任意类型的键值对,通常与 Qt 的其他类型(如 QString, QVariant)结合使用。

  • 重复键处理QMap 不允许重复的键,如果插入一个已存在的键,原有的值将被覆盖。

  • 易于使用的 API:提供了丰富的方法来操作键值对,方便开发者管理数据。

方法描述
QMap<Key, T>()默认构造函数,创建一个空的 QMap
QMap<Key, T>(const QMap<Key, T> &other)拷贝构造函数,复制另一个 QMap 的内容。
~QMap()析构函数,释放内存。
int size() const返回当前键值对的数量。
bool isEmpty() const判断 QMap 是否为空。
void insert(const Key &key, const T &value)插入一个键值对,如果键已存在,值将被覆盖。
T value(const Key &key, const T &defaultValue = T()) const返回指定键的值,如果键不存在则返回默认值。
void remove(const Key &key)移除指定键的元素。
bool contains(const Key &key) const判断是否包含指定的键。
QList<Key> keys() const返回所有键的列表。
QList<T> values() const返回所有值的列表。
QList<T> values(const Key &key) const返回指定键对应的值的列表。
Key firstKey() const返回第一个键。
Key lastKey() const返回最后一个键。
void clear()清空 QMap 中的所有键值对。
QMap<Key, T> &operator=(const QMap<Key, T> &other)赋值运算符,复制另一个 QMap 的内容。
bool operator==(const QMap<Key, T> &other) const判断两个 QMap 是否相等。
#include <QMap>
#include <QString>
#include <QDebug>
​
int main() {QMap<QString, int> grades;
​// 插入键值对grades.insert("Alice", 85);grades.insert("Bob", 90);grades.insert("Charlie", 78);
​// 输出总数qDebug() << "Total students:" << grades.size(); // Total students: 3
​// 获取某个学生的成绩qDebug() << "Alice's grade:" << grades.value("Alice"); // Alice's grade: 85
​// 修改成绩grades["Alice"] = 95; // 更新 Alice 的成绩qDebug() << "Alice's updated grade:" << grades.value("Alice"); // Alice's updated grade: 95
​// 检查某个学生是否存在if (grades.contains("David")) {qDebug() << "David's grade:" << grades.value("David");} else {qDebug() << "David not found."; // David not found.}
​// 移除某个学生grades.remove("Charlie");
​// 输出所有学生的成绩for (const QString &name : grades.keys()) {qDebug() << name << ":" << grades.value(name);}
​// 清空 QMapgrades.clear();qDebug() << "Is empty:" << grades.isEmpty(); // Is empty: true
​return 0;
}

QMap 的性能在大多数场景下都非常优秀。由于采用红黑树实现,其查找、插入和删除操作的平均时间复杂度为 O(log n)。虽然在某些情况下,QMap 的性能可能略逊于 QHash(哈希表实现),但在需要有序存储时,QMap 是更好的选择。

QMap 的使用场景非常广泛,包括但不限于:

  • 配置存储:存储配置信息时,可以使用键值对的形式存储各类配置项,便于查找和修改。

  • 数据索引:在需要根据某种键(如 ID、名称)快速查找数据时,使用 QMap 可以高效地管理这些关系。

  • 有序数据:在需要保持元素顺序的同时又要快速查找和修改的场合,QMap 是一个理想的选择。

QMultiMap

QMultiMap 是 Qt 提供的一种特殊的关联容器,允许多个值与同一个键关联。它类似于 QMap,但不同之处在于 QMultiMap 允许键的重复,适合于需要存储多个值而不想丢失键的场景。

  • 允许重复键QMultiMap 允许多个值与同一个键关联,适合存储一对多关系的数据。

  • 自动排序:与 QMap 一样,QMultiMap 中的键是自动排序的,能够根据键的顺序遍历元素。

  • 快速查找:基于红黑树实现,查找、插入和删除的平均时间复杂度为 O(log n)。

  • 多类型支持:支持存储任意类型的键值对,通常与 Qt 的其他类型(如 QString, QVariant)结合使用。

  • 易于使用的 API:提供了丰富的方法来操作键值对,方便开发者管理数据。

方法描述
QMultiMap<Key, T>()默认构造函数,创建一个空的 QMultiMap
QMultiMap<Key, T>(const QMultiMap<Key, T> &other)拷贝构造函数,复制另一个 QMultiMap 的内容。
~QMultiMap()析构函数,释放内存。
int size() const返回当前键值对的数量。
bool isEmpty() const判断 QMultiMap 是否为空。
void insert(const Key &key, const T &value)插入一个键值对,允许同一个键有多个值。
QList<T> values(const Key &key) const返回指定键对应的所有值的列表。
void remove(const Key &key)移除所有与指定键关联的元素。
bool contains(const Key &key) const判断是否包含指定的键。
QList<Key> keys() const返回所有键的列表。
Key firstKey() const返回第一个键。
Key lastKey() const返回最后一个键。
void clear()清空 QMultiMap 中的所有键值对。
QMultiMap<Key, T> &operator=(const QMultiMap<Key, T> &other)赋值运算符,复制另一个 QMultiMap 的内容。
bool operator==(const QMultiMap<Key, T> &other) const判断两个 QMultiMap 是否相等。
#include <QMultiMap>
#include <QString>
#include <QDebug>
​
int main() {QMultiMap<QString, QString> studentCourses;
​// 插入多个值studentCourses.insert("Alice", "Math");studentCourses.insert("Alice", "Science");studentCourses.insert("Bob", "Math");studentCourses.insert("Charlie", "History");studentCourses.insert("Charlie", "Math");
​// 输出每个学生的课程for (const QString &student : studentCourses.keys()) {QList<QString> courses = studentCourses.values(student);qDebug() << student << "is enrolled in:" << courses;}
​// 移除某个学生的所有课程studentCourses.remove("Alice");
​// 检查是否存在if (!studentCourses.contains("Alice")) {qDebug() << "Alice has been removed from the course list.";}
​// 清空 QMultiMapstudentCourses.clear();qDebug() << "Is empty:" << studentCourses.isEmpty(); // Is empty: true
​return 0;
}

QMultiMap 的性能与 QMap 类似,查找、插入和删除操作的平均时间复杂度为 O(log n)。由于它允许重复键的特性,在管理一对多关系时非常有效。

QMultiMap 适用于多种场景:

  • 多对多关系存储:在需要存储一对多或多对多关系的数据时,QMultiMap 是理想的选择。

  • 分类数据:在需要将数据分类存储时,可以使用相同的键来代表不同的类别。

  • 标签系统:在实现标签系统时,可以将多个标签与同一对象关联,方便管理和查询。

QSet

QSet 是 Qt 提供的一种集合容器,主要用于存储唯一值的集合。它类似于 C++ 标准库中的 std::set,但在使用上更加方便,特别是在与 Qt 其他类的结合使用时。QSet 适合用于需要存储不重复元素的场景,提供快速的查找、插入和删除操作。

  • 唯一性QSet 中的每个元素都是唯一的,不能存储重复的值。

  • 无序性:元素在集合中没有特定的顺序,遍历时的顺序与插入顺序无关。

  • 快速查找:基于哈希表实现,查找、插入和删除操作的平均时间复杂度为 O(1)。

  • 多类型支持:可以存储任意类型的数据,通常与 Qt 的其他类型(如 QString, QVariant)结合使用。

  • 易于使用的 API:提供了丰富的方法来操作集合,方便开发者管理数据。

方法描述
QSet<T>()默认构造函数,创建一个空的 QSet
QSet<T>(const QSet<T> &other)拷贝构造函数,复制另一个 QSet 的内容。
~QSet()析构函数,释放内存。
int size() const返回集合中元素的数量。
bool isEmpty() const判断 QSet 是否为空。
void insert(const T &value)向集合中添加一个新元素,如果元素已存在,则不进行操作。
void remove(const T &value)移除集合中的指定元素。
bool contains(const T &value) const判断集合是否包含指定元素。
QList<T> toList() const将集合转换为 QList
QSet<T> intersect(const QSet<T> &other) const返回与另一个集合的交集。
QSet<T> unite(const QSet<T> &other) const返回与另一个集合的并集。
QSet<T> subtract(const QSet<T> &other) const返回从集合中减去另一个集合后的结果。
void clear()清空集合中的所有元素。
QSet<T> &operator=(const QSet<T> &other)赋值运算符,复制另一个 QSet 的内容。
bool operator==(const QSet<T> &other) const判断两个 QSet 是否相等。
#include <QSet>
#include <QString>
#include <QDebug>
​
int main() {QSet<QString> students;
​// 插入学生姓名students.insert("Alice");students.insert("Bob");students.insert("Charlie");students.insert("Alice"); // 重复插入,不会改变集合
​// 输出当前学生人数qDebug() << "Total students:" << students.size(); // Total students: 3
​// 检查是否包含某个学生if (students.contains("Bob")) {qDebug() << "Bob is in the set.";}
​// 移除某个学生students.remove("Charlie");
​// 输出所有学生姓名for (const QString &name : students) {qDebug() << name;}
​// 清空集合students.clear();qDebug() << "Is empty:" << students.isEmpty(); // Is empty: true
​return 0;
}

QHash

QHash 是 Qt 提供的一种基于哈希表的关联容器,主要用于存储键值对。它允许快速的查找、插入和删除操作,适合需要频繁访问数据的场景。与 QMap 不同的是,QHash 不会自动排序其元素,主要关注数据的存取效率。

  • 键的唯一性QHash 中的每个键都是唯一的,不能存储重复的键。

  • 无序性:元素在集合中没有特定的顺序,遍历时的顺序与插入顺序无关。

  • 快速查找:基于哈希表实现,查找、插入和删除操作的平均时间复杂度为 O(1)。

  • 多类型支持:可以存储任意类型的键值对,通常与 Qt 的其他类型(如 QString, QVariant)结合使用。

  • 易于使用的 API:提供了丰富的方法来操作键值对,方便开发者管理数据。

方法描述
QHash<Key, T>()默认构造函数,创建一个空的 QHash
QHash<Key, T>(const QHash<Key, T> &other)拷贝构造函数,复制另一个 QHash 的内容。
~QHash()析构函数,释放内存。
int size() const返回当前键值对的数量。
bool isEmpty() const判断 QHash 是否为空。
void insert(const Key &key, const T &value)向哈希表中插入一个键值对,如果键已存在,则值将被覆盖。
void remove(const Key &key)移除指定键的元素。
bool contains(const Key &key) const判断是否包含指定的键。
T value(const Key &key, const T &defaultValue = T()) const返回指定键的值,如果键不存在则返回默认值。
QList<Key> keys() const返回所有键的列表。
QList<T> values() const返回所有值的列表。
void clear()清空 QHash 中的所有键值对。
QHash<Key, T> &operator=(const QHash<Key, T> &other)赋值运算符,复制另一个 QHash 的内容。
bool operator==(const QHash<Key, T> &other) const判断两个 QHash 是否相等。
cpp复制代码#include <QHash>
#include <QString>
#include <QDebug>
​
int main() {QHash<QString, int> grades;
​// 插入学生成绩grades.insert("Alice", 85);grades.insert("Bob", 90);grades.insert("Charlie", 78);
​// 输出学生总数qDebug() << "Total students:" << grades.size(); // Total students: 3
​// 获取某个学生的成绩qDebug() << "Alice's grade:" << grades.value("Alice"); // Alice's grade: 85
​// 修改成绩grades["Alice"] = 95; // 更新 Alice 的成绩qDebug() << "Alice's updated grade:" << grades.value("Alice"); // Alice's updated grade: 95
​// 检查某个学生是否存在if (grades.contains("David")) {qDebug() << "David's grade:" << grades.value("David");} else {qDebug() << "David not found."; // David not found.}
​// 移除某个学生grades.remove("Charlie");
​// 输出所有学生的成绩for (const QString &name : grades.keys()) {qDebug() << name << ":" << grades.value(name);}
​// 清空 QHashgrades.clear();qDebug() << "Is empty:" << grades.isEmpty(); // Is empty: true
​return 0;
}

QHash 适用于多种场景,例如:

  • 数据索引:在需要根据某个键快速查找数据时,QHash 是一个理想的选择。

  • 缓存机制:可以使用 QHash 来实现简单的缓存机制,以存储计算结果或数据。

  • 频率统计:在处理需要统计元素出现频率的场景时,QHash 可以轻松存储和更新频率。

相关文章:

Qt Essential Classes

目录 QVariant QFlags QRandomGenerator 经典的Qt容器 QVector QList QMap QMultiMap QSet QHash QVariant 同std::variant是一样的&#xff0c;他是一个更加高级的union。在一个时间下&#xff0c;它虽然实际上只能是一种类型&#xff0c;但是一个variant可以hold住…...

小小猫棒onu替换家用光猫,薅运营商带宽羊毛,突破1000M

小小猫棒onu 一、总体步骤 1 记录原来光猫信息 主要包括SN&#xff0c;ploam密码&#xff0c;loid、loid密码、 mac、上网的vlan id等 一般gpon采用SN、ploam密码、SNploam密码三种中的一种认证方式 一般Epon采用loid&#xff08;逻辑id&#xff09;、mac、loid mac三种中…...

软件测试学习笔记丨Selenium学习笔记:css定位

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/22511 本文为霍格沃兹测试开发学社的学习经历分享&#xff0c;写出来分享给大家&#xff0c;希望有志同道合的小伙伴可以一起交流技术&#xff0c;一起进步~ 说明&#xff1a;本篇博客基于sel…...

python数据处理常用操作

数据处理是机器学习中非常重要的一步&#xff0c;以下是一些常用的操作和示例代码&#xff1a; 1. 数据清洗 处理缺失值&#xff1a; import pandas as pd# 读取数据 df pd.read_csv(data.csv)# 删除缺失值 df.dropna(inplaceTrue)# 用均值填充缺失值 df.fillna(df.mean(), i…...

解决minio跨域问题

MinIO 支持跨域资源共享(CORS)&#xff0c;允许你配置跨域请求的相关策略。以下是一个基本的CORS配置示例&#xff0c;你可以在MinIO的配置文件&#xff08;例如config.json&#xff09;中设置这些策略&#xff1a; 在Linux中 root/.minio 目录下如果没有就新建一个 config.jso…...

python 跳过当前循环

在 Python 中&#xff0c;可以使用 continue 语句来跳过当前循环的剩余部分&#xff0c;并继续下一次循环。continue 语句用于跳过循环体中剩余的语句&#xff0c;并立即开始下一次迭代。 以下是一个简单的示例&#xff0c;演示了如何在 for 循环中使用 continue 语句&#xf…...

数据库数据恢复—Oracle ASM磁盘组掉线 ,ASM实例无法挂载的数据恢复案例

Oracle数据库数据恢复环境&故障&#xff1a; Oracle ASM磁盘组由4块磁盘组成。Oracle ASM磁盘组掉线 &#xff0c;ASM实例不能mount。 Oracle数据库故障分析&恢复方案&#xff1a; 数据库数据恢复工程师对组成ASM磁盘组的磁盘进行分析。对ASM元数据进行分析发现ASM存储…...

jupyter notebook改变默认启动路径

安装好Anaconda 3以后&#xff0c;就可以使用Jupyter notebook了&#xff0c;但是我们打开Jupyter notebook后&#xff0c;发现界面是一个默认的目录&#xff0c;这个目录在哪里&#xff1f;如果想把自己写的程序文件保存在自己新建的一个文件夹里&#xff0c;修改默认目录到自…...

libevent源码剖析-基本数据结构

1 简介 前面系列文章对libevent源码的主体结构&#xff0c;从reactor框架实现&#xff0c;到evbuffer和bufferevent实现原理&#xff0c;及libevent的例子进行了剖析&#xff0c;自此&#xff0c;我们便可基于libevent开发app了。 从本文开始&#xff0c;主要来介绍下libevent源…...

往期文章汇总——射频测量+无线通信+软件无线电+6G科普

本节目录 一、射频测量系列往期链接 二、无线通信系列往期链接 三、软件无线电系列往期链接 四、6G科普系列往期链接本节内容 一、射频测量系列往期链接 射频测量 | 滤波器的关注指标 射频测量 | 射频电路中的负载与滤波器 射频测量 | 射频衰减器的功率系数 射频测量 | 衰减…...

微信小程序 - 深 / 浅拷贝实现方法,微信小程序深拷贝与浅拷贝,函数方法封装直接调用使用,深拷贝cloneDeep和浅拷贝clone(深复制和浅复制)

前言 在微信小程序中,你无法 直接使用常规浏览器环境中的深浅拷贝方法。 但可以借助 utils.js 实现,下面是方法。 创建深浅拷贝函数 依次打开小程序目录【utils】→【utils.js】,写入深拷贝函数并暴露出去。 // utils.js// 对象深拷贝函数 const deepClone = function(in…...

Log4Net配置详解及输出自定义消息类示例代码

1.简单使用实例 1.1 添加log4net.dll的引用。 在NuGet程序包中搜索log4net并添加&#xff0c;此次我所用版本为2.0.17。如下图&#xff1a; 1.2 添加配置文件 右键项目&#xff0c;添加新建项&#xff0c;搜索选择应用程序配置文件&#xff0c;命名为log4net.config&#xff0c…...

C++在实际项目中的应用第二节:C++与区块链

第五章&#xff1a;C在实际项目中的应用 第二课&#xff1a;C与区块链 区块链技术因其去中心化、不可篡改和透明性而受到广泛关注。在这门课程中&#xff0c;我们将深入探讨区块链的基本原理、智能合约的开发以及实际应用的案例分析&#xff0c;重点使用 C 作为实现语言&…...

浅记React面试丢人时刻

前提 去面试了&#xff0c;技术面完一轮之后&#xff0c;突发的来了一次React的考察&#xff0c;哥们&#xff0c;猝不及防之下&#xff0c;脑袋直接清空&#xff0c;啥也想不起来了。现在想想&#xff0c;实属丢人&#xff0c;记录一下啥也没答出来的面试&#xff0c;钉在耻辱…...

Python入门:学会Python装饰器让你的代码如虎添翼!(Python如何不改动原有函数代码添加一些额外的功能)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 什么是Python装饰器📝 如何编写Python装饰器📝 带参数的装饰器📝 Python装饰器的使用场景📝 注意事项📝 多装饰器的使用⚓️ 相关链接 ⚓️📖 介绍 📖 你是不是在写代码的时候,常常会想有没有…...

【C++】哈希冲突的解决办法:闭散列 与 开散列

哈希冲突解决 上一篇博客提到了&#xff0c;哈希函数的优化可以减小哈希冲突发生的可能性&#xff0c;但无法完全避免。本文就来探讨一下解决哈希冲突的两种常见方法&#xff1a;闭散列和开散列 1.闭散列 闭散列也叫开放定址法&#xff0c;发生哈希冲突时&#xff0c;如果哈…...

复刻系列-原神 5.1 版本先行展示页

复刻原神 5.1 版本先行展示页 0. 视频 BilBil站视频演示 复刻-原神5.1版本先行展示页 1. 基本信息 作者: 啊是特嗷桃系列: 复刻系列官方的网站: 《原神》官方网站-全新5.1版本「命定将焚的虹光」上线&#xff01;复刻的网站: 《原神》复刻网站-全新5.1版本「命定将焚的虹光」…...

STM32 第3章 如何用串口下载程序

时间:2024.10.28 一、学习内容 1、安装USB转串口驱动 1.1串口下载连接示意图 1、USB转串口模块在开发板上是一个独立的模块,可通过调帽与其他串口连接,USART1/2/3/4/5 2、只有USART1才具有串口下载的功能。 3、CH340是电平转换芯片,将电脑端输出的USB电平和单片机输…...

HT71782 20V,15A全集成同步升压转换器

1、特征 输入电压范围VN:2.7V-20V 输出电压范围VouT:4.5V-20V 可编程峰值电流:15A 高转换效率: 93%(VIN7.4V,VoUT15.5V,IouT 1.5A) 轻载条件下两种调制方式:脉频调制(PFM)和 强制脉宽调试(FPWM) 支持两种tr/t模式&#xff0c;应对EMI挑战 低关断功耗&#xff0c;关断电流1uA 可…...

[含文档+PPT+源码等]精品基于PHP实现的培训机构信息管理系统的设计与实现

基于PHP实现的培训机构信息管理系统的设计与实现背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、社会发展与教育需求 随着经济的不断发展和人口数量的增加&#xff0c;教育培训行业迎来了前所未有的发展机遇。家长对子女教育的重视程度日益提高&#xff0c;课外…...

亚信安全DeepSecurity中标知名寿险机构云主机安全项目

近日&#xff0c;亚信安全DeepSecurity成功中标国内知名寿险机构的云主机安全项目。亚信安全凭借在云主机安全防护领域的突出技术优势&#xff0c;结合安全运营的能力&#xff0c;以“实战化”为指导&#xff0c;为用户提供无惧威胁攻击、无忧安全运营的一站式云安全体系&#…...

论文解析八: GAN:Generative Adversarial Nets(生成对抗网络)

目录 1.GAN&#xff1a;Generative Adversarial Nets&#xff08;生成对抗网络&#xff09;1、标题 作者2、摘要 Abstract3、导言 IntroductionGAN的介绍 4、相关工作 Related work5、模型 Adversarial nets总结 6.理论计算 Theoretical Results具体算法公式全局优化 Global O…...

【ARM】ARM架构参考手册_Part B 内存和系统架构(2)

目录 2.1 关于系统控制协处理器 2.2 寄存器 2.1 关于系统控制协处理器 所有标准内存和系统设施都由协处理器15&#xff08;CP15&#xff09;控制&#xff0c;因此它被称为系统控制协处理器。有些设施也使用其他控制方法&#xff0c;这些方法在描述这些设施的章节中有描述。例…...

HttpServer模块 --- 封装TcpServer支持Http协议

目录 模块设计思想 模块代码实现 模块设计思想 本模块就是设计一个HttpServer模块&#xff0c;提供便携的搭建http协议的服务器的方法。 那么这个模块需要如何设计呢&#xff1f; 这还需要从Http请求说起。 首先http请求是分为静态资源请求和功能性请求的。 静态资源请求…...

蓝牙资讯|iOS 18.1 正式版下周推送,AirPods Pro 2耳机将带来助听器功能

苹果公司宣布将在下周发布 iOS 18.1 正式版&#xff0c;同时确认该更新将为 AirPods Pro 2 耳机带来新增“临床级”助听器功能。在启用功能后&#xff0c;用户首先需要使用 AirPods 和 iPhone 进行简短的听力测试&#xff0c;如果检测到听力损失&#xff0c;系统将创建一项“个…...

C语言之环形缓冲区概述及实现

在C语言中存在一种高效的数据结构&#xff0c;叫做环形缓存区&#xff0c;其被广泛用于处理数据流与缓存区的管理。如&#xff1a;数据的收发、程序层级之间的数据交换、硬件接收大量数据的场景&#xff0c;同时也可配合DMA实现通信协议收发数据&#xff0c;已确保流量控制、数…...

C++Socket通讯样例(服务端)

1. 创建Socket实例并开启。 private int OpenTcp(int port, string ip "") {//1. 开启服务端try{_tcpServer new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAddr IPAddress.Any;if (ip ! "" && i…...

【学术会议论文投稿】大数据治理:解锁数据价值,引领未来创新

第六届国际科技创新学术交流大会&#xff08;IAECST 2024&#xff09;_艾思科蓝_学术一站式服务平台 更多学术会议请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、大数据治理的定义 二、大数据治理的重要性 三、大数据治理的核心组件 四、大数据治理的实践案例…...

location中href和replace的区别

1.有两种方式&#xff1a; a、使用 location.href&#xff1a;window.location.href“success.html”; b、使用location.replace&#xff1a;window.location.replace(“new_file.html”); 2.区别是什么&#xff1f; 结果&#xff1a;href相当于打开一个新页面&#xff0c;…...

基于Spring Boot的在线摄影工作室开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…...

PHP关于简单企业网站开发过程简介/网站外链的优化方法

综述 算是笔记吧&#xff01;计算机视觉主要任务划分&#xff1a; Semantic segmentation是pixel oriented。也就是面向像素的&#xff0c;事实上这种训练数据需要在每一个pixel上提供label。ClassificationLocalization 识别单个物品并且识别位置&#xff08;E.g, draw box&…...

动态效果酷炫的网站/搜索引擎营销的英文缩写是

嗯&#xff0c;今天好不容易把鸽了好久的缩点给弄完了……感觉好像……很简单&#xff1f; 算法的目的&#xff0c;其实就是在有向图上&#xff0c;把一个强连通分量缩成一个点……然后我们再对此搞搞事情&#xff0c;\(over\) 哦对&#xff0c;时间复杂度很显然是\(\Theta(n)\…...

贵港公司做网站/网站分析

计算机应用基础(WIN7)形成性考核册1答案作业1一、基础知识选择题1、以微处理器为核心组成的微型计算机属于( D )计算机。A、机械 B、电子管 C、晶体管 D、集成电路2、第一台电子计算机诞生于( C )A1958年 B1942年 C 1946年 D 1948年3、第一台电子计算机使用的主要逻辑元件是( B…...

页面设计计划/北京seo业务员

LinkIt_for_RTOS_Firmware_Update_Developers_Guide--用于实时操作系统固件更新开发指南的MediaTek Linkit™开发平台 MediaTek Linkit™SDK v4支持固件空中更新(FOTA)更新&#xff0c;这是一种广泛采用的成本和时间高效的解决方案&#xff0c;用于更新连接设备上的固件。开发…...

海南房产网站开发/广告推广方案怎么写

本文以一个现代的、实际的个人电脑为对象&#xff0c;分析其中CPU&#xff08;Intel Core 2 Duo 3.0GHz&#xff09;以及各类子系统的运行速度——延迟和数据吞吐量。通过粗略的估算PC各个组件的相对运行速度&#xff0c;希望能给大家留下一个比较直观的印象。本文中的数据来自…...

专业建站公司服务/关键词排名提升工具

这是一个基于MVCDAO的留言管理系统&#xff0c;包含增删改查&#xff0c;其中查询&#xff0c;有全部查询和按关键字进行模糊查询的功能。文章底部附件是源码程序。大家共同学习&#xff0c;共同进步。具体如下&#xff1a; NoteDAO.java package cn.mldn.lxh.note.dao ;import…...