C++ Qt框架中的各种集合详解
文章目录
- [C++ Qt框架中的各种集合详解](#C++ Qt框架中的各种集合详解)
一、QList
QList
是一个动态数组,类似于C++标准库的std::vector。它可以存储各种类型的元素,并提供了插入、删除和访问元素的方法。
cpp
#include <QList>
int main() {
QList<int> numbers;
numbers << 1 << 2 << 3 << 4;
// 访问元素
int secondNumber = numbers.at(1); // 2
// 插入元素
numbers.insert(2, 5);
// 删除元素
numbers.removeOne(3);
return 0;
}
- 添加和插入元素
cpp
QList<int> numbers;
numbers.append(1); // 在末尾添加元素
numbers.prepend(0); // 在开头添加元素
numbers.insert(2, 5); // 在索引位置插入元素
- 访问元素
cpp
int value = numbers.at(1); // 访问索引为 1 的元素
int firstValue = numbers.first(); // 第一个元素
int lastValue = numbers.last(); // 最后一个元素
- 修改元素
cpp
numbers[0] = 10; // 修改索引为 0 的元素
numbers.replace(1, 20); // 替换索引为 1 的元素
- 删除元素
cpp
numbers.removeAt(2); // 移除索引为 2 的元素
numbers.removeOne(10); // 移除第一个值为 10 的元素
numbers.removeAll(5); // 移除所有值为 5 的元素
numbers.clear(); // 清空列表
- 查找元素
cpp
int index = numbers.indexOf(20); // 查找值为 20 的元素的索引
int lastIndex = numbers.lastIndexOf(20); // 查找最后一个值为 20 的元素的索引
bool contains = numbers.contains(30); // 判断是否包含值为 30 的元素
- 遍历元素
cpp
foreach (int num, numbers) {
// 遍历所有元素
}
for (int i = 0; i < numbers.size(); ++i) {
int num = numbers[i];
// 使用索引遍历
}
- 获取列表信息
cpp
int size = numbers.size(); // 获取列表大小
bool isEmpty = numbers.isEmpty(); // 检查列表是否为空
- 排序
cpp
numbers.sort(); // 对列表进行默认升序排序
numbers.sort(Qt::DescendingOrder); // 对列表进行降序排序
- 复制和合并
cpp
QList<int> copy = numbers; // 复制列表
QList<int> merged = numbers + otherList; // 合并两个列表
numbers << 100 << 200; // 通过添加元素来合并列表
二、QVector
QVector
类似于 QList
,但适用于需要高效连续内存存储的情况。
cpp
#include <QVector>
int main() {
QVector<QString> names;
names << "Alice" << "Bob" << "Charlie";
// 使用索引访问元素
QString secondName = names[1]; // "Bob"
return 0;
}
QVector的常用的添加、修改、访问、修改、查找以及遍历元素的方式和QList是一致的,可以直接参考QList。
三、QMap
QMap
是一个关联数组,存储键-值对,键是唯一的,并按键的排序顺序排列。
cpp
#include <QMap>
int main() {
QMap<QString, int> ageMap;
ageMap.insert("Alice", 25);
ageMap.insert("Bob", 30);
ageMap.insert("Charlie", 28);
// 通过键访问值
int bobAge = ageMap.value("Bob"); // 30
return 0;
}
- 添加键值对
cpp
QMap<QString, int> ageMap;
ageMap.insert("Alice", 25);
ageMap.insert("Bob", 30);
ageMap["Charlie"] = 28; // 使用运算符重载添加键值对
- 访问值
cpp
int aliceAge = ageMap.value("Alice"); // 获取键为 "Alice" 的值
int bobAge = ageMap["Bob"]; // 使用键访问值
- 修改值
cpp
ageMap["Charlie"] = 29; // 修改键为 "Charlie" 的值
- 删除键值对
cpp
ageMap.remove("Alice"); // 移除键为 "Alice" 的键值对
ageMap.clear(); // 清空映射
- 检查键是否存在
cpp
bool containsBob = ageMap.contains("Bob"); // 检查是否包含键 "Bob"
- 遍历键值对
cpp
foreach (const QString &name, ageMap.keys()) {
int age = ageMap.value(name);
// 遍历所有键值对的键
}
QMapIterator<QString, int> i(ageMap);
while (i.hasNext()) {
i.next();
QString name = i.key();
int age = i.value();
// 使用迭代器遍历键值对
}
- 获取映射信息
cpp
int size = ageMap.size(); // 获取映射中键值对的数量
bool isEmpty = ageMap.isEmpty(); // 检查映射是否为空
- 排序
QMap 默认按照键的升序进行排序。如果需要自定义排序方式,可以使用自定义比较函数或者使用QMap::insertMulti()
来插入多个相同键的值。
cpp
ageMap.insertMulti("Alice", 24);
ageMap.insertMulti("Alice", 26);
// 现在 ageMap["Alice"] 会包含多个值
- 复制和合并
cpp
QMap<QString, int> copyMap = ageMap; // 复制映射
ageMap.unite(otherMap); // 合并映射,相同键的值会合并
四、QHash
QHash
是一个散列表,存储键-值对,具有快速查找性能,但不保持键的顺序。
cpp
#include <QHash>
int main() {
QHash<QString, QString> cityCountry;
cityCountry.insert("Paris", "France");
cityCountry.insert("Tokyo", "Japan");
cityCountry.insert("New York", "USA");
// 使用键查找值
QString tokyoCountry = cityCountry.value("Tokyo"); // "Japan"
return 0;
}
- 添加键值对
cpp
QHash<QString, int> ageHash;
ageHash.insert("Alice", 25);
ageHash.insert("Bob", 30);
ageHash["Charlie"] = 28; // 使用运算符重载添加键值对
- 访问值
cpp
int aliceAge = ageHash.value("Alice"); // 获取键为 "Alice" 的值
int bobAge = ageHash["Bob"]; // 使用键访问值
- 修改值
cpp
ageHash["Charlie"] = 29; // 修改键为 "Charlie" 的值
- 删除键值对
cpp
ageHash.remove("Alice"); // 移除键为 "Alice" 的键值对
ageHash.clear(); // 清空哈希表
- 检查键是否存在
cpp
bool containsBob = ageHash.contains("Bob"); // 检查是否包含键 "Bob"
- 遍历键值对
cpp
foreach (const QString &name, ageHash.keys()) {
int age = ageHash.value(name);
// 遍历所有键值对的键
}
QHashIterator<QString, int> i(ageHash);
while (i.hasNext()) {
i.next();
QString name = i.key();
int age = i.value();
// 使用迭代器遍历键值对
}
- 获取哈希表信息
cpp
int size = ageHash.size(); // 获取哈希表中键值对的数量
bool isEmpty = ageHash.isEmpty(); // 检查哈希表是否为空
- 复制和合并
cpp
QHash<QString, int> copyHash = ageHash; // 复制哈希表
ageHash.unite(otherHash); // 合并哈希表,相同键的值会合并
五、QSet
QSet
是一个无序集合,存储不重复的值。它不会保持特定的顺序
cpp
#include <QSet>
int main() {
QSet<int> numbers;
numbers << 3 << 5 << 7 << 5; // 注意:重复的值只会存储一次
// 判断值是否存在
bool containsSeven = numbers.contains(7); // true
return 0;
}
- 添加值
cpp
QSet<QString> names;
names.insert("Alice");
names.insert("Bob");
- 检查值是否存在
cpp
bool containsAlice = names.contains("Alice"); // 检查是否包含值 "Alice"
- 删除值
cpp
names.remove("Alice"); // 移除值 "Alice"
names.clear(); // 清空集合
- 遍历值
cpp
foreach (const QString &name, names) {
// 遍历所有值
}
QSetIterator<QString> i(names);
while (i.hasNext()) {
QString name = i.next();
// 使用迭代器遍历值
}
- 获取集合信息
cpp
int size = names.size(); // 获取集合中值的数量
bool isEmpty = names.isEmpty(); // 检查集合是否为空
- 复制和合并
cpp
QSet<QString> copySet = names; // 复制集合
names.unite(otherSet); // 合并集合,会保留不重复的值
六、QLinkedList
QLinkedList
是一个双向链表,适用于频繁插入和删除操作,但是在访问元素时性能相对较差。
cpp
#include <QLinkedList>
int main() {
QLinkedList<QString> names;
names << "Alice" << "Bob" << "Charlie";
// 在链表中插入元素
names.insert(names.begin(), "David");
// 从链表中移除元素
names.removeOne("Bob");
return 0;
}
- 添加元素
cpp
QLinkedList<QString> names;
names.append("Alice"); // 在末尾添加元素
names.prepend("Bob"); // 在开头添加元素
names.insert(++names.begin(), "Charlie"); // 在指定位置插入元素
- 访问元素
cpp
QString first = names.first(); // 获取第一个元素
QString last = names.last(); // 获取最后一个元素
- 修改元素
cpp
*names.begin() = "David"; // 修改第一个元素
- 删除元素
cpp
names.erase(names.begin()); // 移除第一个元素
names.removeOne("Charlie"); // 移除值为 "Charlie" 的元素
names.clear(); // 清空链表
- 遍历元素
cpp
foreach (const QString &name, names) {
// 遍历所有元素
}
QLinkedListIterator<QString> i(names);
while (i.hasNext()) {
QString name = i.next();
// 使用迭代器遍历元素
}
- 获取链表信息
cpp
int size = names.size(); // 获取链表中元素的数量
bool isEmpty = names.isEmpty(); // 检查链表是否为空
- 复制和合并
cpp
QLinkedList<QString> copyList = names; // 复制链表
names += otherList; // 合并链表
七、QStack
QStack
是一个堆栈,支持后进先出(LIFO)操作。
cpp
#include <QStack>
int main() {
QStack<int> stack;
stack.push(10);
stack.push(20);
stack.push(30);
// 弹出栈顶元素
int poppedValue = stack.pop(); // 30
return 0;
}
- 入栈
cpp
QStack<int> stack;
stack.push(10); // 将 10 入栈
stack.push(20); // 将 20 入栈
stack.push(30); // 将 30 入栈
- 出栈
cpp
int poppedValue = stack.pop(); // 弹出栈顶元素,poppedValue = 30
- 获取栈顶元素
cpp
int topValue = stack.top(); // 获取栈顶元素,但不弹出
- 检查栈是否为空
cpp
bool isEmpty = stack.isEmpty(); // 检查栈是否为空
- 获取栈的大小
cpp
int size = stack.size(); // 获取栈中元素的数量
- 遍历栈
cpp
while (!stack.isEmpty()) {
int value = stack.pop(); // 从栈中依次弹出所有元素
}
八、QQueue
QQueue
是一个队列,支持先进先出(FIFO)操作。
cpp
#include <QQueue>
int main() {
QQueue<QString> tasks;
tasks.enqueue("Task 1");
tasks.enqueue("Task 2");
tasks.enqueue("Task 3");
// 出队列
QString nextTask = tasks.dequeue(); // "Task 1"
return 0;
}
- 入队
cpp
QQueue<QString> tasks;
tasks.enqueue("Task 1"); // 将任务 1 入队
tasks.enqueue("Task 2"); // 将任务 2 入队
tasks.enqueue("Task 3"); // 将任务 3 入队
- 出队
cpp
QString dequeuedTask = tasks.dequeue(); // 出队一个任务,dequeuedTask = "Task 1"
- 获取队首元素
cpp
QString frontTask = tasks.first(); // 获取队首元素,但不出队
- 检查队列是否为空
cpp
bool isEmpty = tasks.isEmpty(); // 检查队列是否为空
- 获取队列的大小
cpp
int size = tasks.size(); // 获取队列中元素的数量
- 遍历对列
cpp
while (!tasks.isEmpty()) {
QString task = tasks.dequeue(); // 从队列中依次出队所有任务
}
九、QMultiMap
QMultiMap
是 Qt 中的一个关联数组集合类,允许一个键对应多个值。它类似于 QMap
,但不同的是它允许多个相同的键存在,并且会按照键的插入顺序保持排序。
cpp
#include <QMultiMap>
int main() {
QMultiMap<QString, int> scores;
scores.insert("Alice", 90);
scores.insert("Bob", 85);
scores.insert("Alice", 95);
// 获取所有 Alice 的分数
QList<int> aliceScores = scores.values("Alice"); // [90, 95]
return 0;
}
- 创建和添加键值对
cpp
QMultiMap<QString, int> scores;
scores.insert("Alice", 90);
scores.insert("Bob", 85);
scores.insert("Alice", 95); // 允许同一个键对应多个值
- 访问值
cpp
QList<int> aliceScores = scores.values("Alice"); // 获取键为 "Alice" 的所有值
- 遍历键值对
cpp
foreach (const QString &name, scores.uniqueKeys()) {
QList<int> values = scores.values(name);
// 遍历所有键值对的键,并获取对应的值列表
}
- 修改值
cpp
QList<int> aliceScores = scores.values("Alice");
if (!aliceScores.isEmpty()) {
scores.insert("Alice", aliceScores.first() + 5); // 修改第一个值
}
- 删除键值对
cpp
QList<int> aliceScores = scores.values("Alice");
if (!aliceScores.isEmpty()) {
scores.insert("Alice", aliceScores.first() + 5); // 修改第一个值
}
- 获取多重映射信息
cpp
int size = scores.size(); // 获取多重映射中键值对的数量
bool isEmpty = scores.isEmpty(); // 检查多重映射是否为空
十、QMultiHash
QMultiHash
是 Qt 中的一个散列表(哈希表)集合类,允许一个键对应多个值。与 QMultiMap
类似,但不同的是 QMultiHash
不会保持键的插入顺序。
- 创建和添加键值对
cpp
QMultiHash<QString, int> scores;
scores.insert("Alice", 90);
scores.insert("Bob", 85);
scores.insert("Alice", 95); // 允许同一个键对应多个值
- 访问值
cpp
QList<int> aliceScores = scores.values("Alice"); // 获取键为 "Alice" 的所有值
- 遍历键值对
cpp
QList<QString> keys = scores.keys(); // 获取所有键
foreach (const QString &key, keys) {
QList<int> values = scores.values(key);
// 遍历所有键值对的键,并获取对应的值列表
}
- 修改值
cpp
QList<int> aliceScores = scores.values("Alice");
if (!aliceScores.isEmpty()) {
scores.insert("Alice", aliceScores.first() + 5); // 修改第一个值
}
- 删除键值对
cpp
scores.remove("Alice"); // 移除键为 "Alice" 的所有键值对
scores.remove("Alice", 95); // 移除键为 "Alice",值为 95 的键值对
scores.clear(); // 清空多重哈希
- 获取多重哈希信息
cpp
int size = scores.size(); // 获取多重哈希中键值对的数量
bool isEmpty = scores.isEmpty(); // 检查多重哈希是否为空
QMultiHash
提供了一种使用散列表来实现多重映射的方式,适用于需要一个键可以对应多个值的情况。与 QMultiMap
不同的是,QMultiHash
不会保持键的插入顺序,因此在需要快速查找的场景中可能更具有优势。无论是需要一对一映射还是一对多映射,都可以根据需求选择适当的集合类。