【Qt】之QSet使用

描述

QSet类是一个模板类,它提供基于散列表的集合。

QSet是Qt的通用容器类之一。它以未指定的顺序存储值,并提供非常快速的值查找。在内部,QSet是作为QHash实现的。

下面是一个带有QString值的QSet示例:

cpp 复制代码
QSet<QString> set;

插入方式1:

cpp 复制代码
  set.insert("one");
  set.insert("three");
  set.insert("seven");

插入方式2:

cpp 复制代码
set << "twelve" << "fifteen" << "nineteen";

判断是否包含:

cpp 复制代码
  if (!set.contains("ninety-nine"))
      ...

如果要浏览存储在QSet中的所有值,可以使用迭代器。QSet支持java风格的迭代器(QSetIterator和QMutableSetIterator)和stl风格的迭代器(QSet::iterator和QSet::const_iterator)。

下面是QSet使用java风格的迭代器:

cpp 复制代码
  QSetIterator<QWidget *> i(set);
  while (i.hasNext())
      qDebug() << i.next();

下面是使用STL-style风格迭代器:

cpp 复制代码
  QSet<QWidget *>::const_iterator i = set.constBegin();
  while (i != set.constEnd()) {
      qDebug() << *i;
      ++i;
  }

QSet是无序的,因此不能假定迭代器的序列是可预测的。如果需要按键排序,请使用QMap。

要在QSet中导航,还可以使用foreach:

cpp 复制代码
  QSet<QString> set;
  ...
  foreach (const QString &value, set)
      qDebug() << value;

可以使用remove()从集合中删除项。还有一个clear()函数可以删除所有项。

QSet的值数据类型必须是可赋值的数据类型。例如,不能将QWidget存储为值;相反,存储一个QWidget *。此外,该类型必须提供operator==(),并且还必须有一个全局qHash()函数,该函数返回键类型参数的散列值。有关QHash()支持的类型列表,可以参考QHash文档。

在内部,QSet使用散列表来执行查找。哈希表自动增长和收缩,以提供快速查找而不浪费内存。如果已经大致知道QSet将包含多少元素,仍然可以通过调用reserve()来控制哈希表的大小,但这不是获得良好性能所必需的。还可以调用capacity()来检索哈希表的大小。

示例

cpp 复制代码
#include <QDebug>
#include <QSet>
#include <QSetIterator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSet<QString> set;
    // 重置大小
    set.reserve(10);
    // 输出容量
    qDebug().noquote() << "容量 :" << set.capacity();
    // 插入数据
    set.insert("1");
    set.insert("12");
    set.insert("21");
    set.insert("212");
    set.insert("121");
    // 输出实际大小
    qDebug().noquote() << "实际大小:" << set.size();
    // 输出内容
    qDebug().noquote() << "输出内容 :" << set;

    // 遍历
    /// 1. java style
    QSetIterator<QString> it_java(set);
    while (it_java.hasNext()) {
        qDebug().noquote() << "java_style : " << it_java.next();
    }

    /// 2. stl style
    QSet<QString>::const_iterator it_stl = set.cbegin();
    while (it_stl != set.cend()) {
        qDebug().noquote() << "stl_style : " << *it_stl;

        ++it_stl;
    }

    // 是否包含
    if(set.contains("121"))
        qDebug().noquote() << "" << "存在";
    else
        qDebug().noquote() << "" << "不存在";

    // 是否是空
    qDebug().noquote() << "是否为空 :" << set.isEmpty();
    
    // 移除某值
    set.remove("121");
    
    // 输出成QList
    QList<QString> listStrs = set.toList();
    qDebug().noquote() << "输出成QList :" << listStrs;
    
    // 输出所有元素
    qDebug().noquote() << "输出元素 :" << set.values();
    
    // 清除
    set.clear();
    
    // 是否为空
    qDebug().noquote() << "是否为空 :" << set.isEmpty();


    return a.exec();
}

结果

使用场景

  1. 消除重复项:如果有一个包含重复项的列表或数组,并且想要消除重复项,可以使用QSet。QSet会自动删除重复的元素,只保留唯一的元素。
  2. 快速查找:QSet提供了高效的插入、查找和删除操作。如果需要频繁地查找元素是否存在于一个集合中,QSet是一个很好的选择。它的查找操作的时间复杂度接近于O(1),因此非常快速。
  3. 集合运算:QSet支持常见的集合运算,如并集、交集和差集。可以使用QSet来执行这些操作,对两个集合进行合并、比较或找出它们的共同元素。
  4. 存储唯一标识符:在某些情况下,可能需要存储一组唯一标识符,例如数据库中的唯一ID或网络中的唯一连接。QSet可以方便地存储这些标识符,并确保每个标识符只出现一次。
  5. 跟踪状态:如果需要跟踪一组对象的状态,并确保每个状态只出现一次,可以使用QSet。例如,在一个游戏中,可能需要跟踪玩家已经访问过的关卡,以确保他们不会重复访问。

结论

平平无奇

相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript