[QT]QList 相关接口

一、概念

QList是Qt的泛型容器类之一。它将数据存储在一个列表中,该列表提供基于索引的快速访问以及基于索引的插入和删除。

QList、QLinkedList 和 QVector 提供了类似的 API 和功能。它们通常是可互换的,但性能有所区别。(以前 QVector 在 Qt 5 中是一个不同的类,但现在是一个简单的 QList 别名)

QVector 应该是默认首选的容器

QList是最广泛用于Qt API中传递值的容器

QList不是指针结构体类型的链表,真正的结构体指针链表是 QLinkedList

二、存储的数据类型

QList可以保存基本数据类型的,如int,double,bool等;但是在存储QObject对象及其子类对象时,不能直接存对象本身,而是只能存对象的地址;

三、QList的相关接口:

1.初始化和构造

cpp 复制代码
    //1.默认构造
    QList<int>list1;
    //2.初始化列表构造
    QList<int>list2 = {1,2,3,4};
    //3.拷贝构造
    QList<int>list3 = list2;
    //4.指定大小和初始值
   QList<int> list4;
    list4 << 100 << 101 << 102 << 103;  //4个元素,值都是100

2.添加元素

cpp 复制代码
//1.append尾加
   list5.append("DDD");
//2.prepend 头加
   list5.prepend("000");
//3.insert 指定位置插入
   list5.insert(2,"111");
//4.<<添加
   list5<<"DDD"<<"EEE";
//5.+添加
   list5 +={"DDD","EEE","FFF","GGG","FFF","AAA"};

3.访问元素

cpp 复制代码
//1.[] 非const的方式访问,可修改
qDebug()<<"list5[0]:"<<list5[0];
//2.at 常量访问
 qDebug()<<"list5.at(1):"<<list5.at(1);
//3.first第一个元素 last最后一个元素
qDebug()<<"list5.first():"<<list5.first()<<",last:"<<list5.last();
//4.value 安全访问,越界返回默认值
qDebug()<<"list5.value():"<<list5.value(5);
QString data = list5.value(10);//越界访问返回"";
qDebug()<<"list5.value(10):"<<list5.value(10);
qDebug()<<"list5.value(12):"<<list5.value(12,"UnKnown");//越界访问返UnKnown

4.修改元素

cpp 复制代码
    //1.通过索引修改
    list5[0] = "ABB";
    //2.replace 替换指定的位置
    list5.replace(1,"bbb");
    //3.swap交换两个位置的元素
    std::swap(list5[1],list5[3]);
    QList<QString> list6={"Apple","banana","orange","pear"};
    list5.swap(list6);
    //4.move移动元素到新的位置
    list5.move(0,2);

5.删除元素

cpp 复制代码
	//1.removeAt 删除指定位置
		list5.removeAt(0);
	//2.removeFirst removeLast
		list5.removeFirst();
		list5.removeLast();
	//3.removeOne 删除第一个匹配的元素
		list5.append("AAA");
     list5.removeOne("AAA");
    //4.删除所有匹配的元素
    list5.append("AAA");
    list5.insert(5,"AAA");
    list5.removeAll("AAA");
    qDebug()<<"size:"<<list5.size();
    //5.clear 清除所有
    list5.clear();
    qDebug()<<"size:"<<list5.size();
    //6.takeAt 删除并返回该元素
    QString at2 = list5.takeAt(2);
    qDebug()<<"at2:"<<at2;

6.查找和查询

cpp 复制代码
 //1.contains - 是否包含
    bool hasAaa = list5.contains("Aaa");
 //2.indexof 查找第一次出现的位置
    int index = list5.indexOf("Aaa");
    int index2 = list5.indexOf("FFF");
    qDebug()<<"hasAaa:"<<hasAaa<<", indexOf Aaa"<<index<<",indexOf FFF"<<index2;
 //3.lastIndexOf - 查找最后一次出现的位置
    int index3 = list5.lastIndexOf("FFF");
    qDebug()<<"lastIndexOf FFF:"<<index3;
 //4.count - 统计出现次数
    int count = list5.count("FFF");
    qDebug()<<"count FFF:"<<count;
 //5.startsWith / endsWith 第一个/最后一个元素是否是某个值
    bool bstart = list5.startsWith("FFF");
    bool bstart2 = list5.startsWith("AAA");
    bool bEnd = list5.endsWith("FFF");
    bool bEnd2 = list5.endsWith("AAA");
    qDebug()<<"bstart:"<<bstart<<","<<bstart2<<"bEnd:"<<bEnd<<","<<bEnd2;

7.容量相关

cpp 复制代码
    QList<QString> list5;
    list5 << "AAA" << "BBB" << "CCC";
    //1.size count length元素的个数
    qDebug()<<"size:"<<list5.size()<<" count:"<<list5.count()<<" length:"<<list5.length();
    //2.isEmpty 判空
    qDebug()<<"isEmpty:"<<list5.isEmpty();
    //capacity - 当前容量 QT6 List才新增的
    list5.reserve(100);
    qDebug() << list5.capacity();
    //3.reserve预分配内存 预分配空间,避免频繁重新分配
    list5.reserve(50);
    qDebug()<<"reserve:"<<list5.size();
    //4.resize 调整大小 QT6 List才新增的
   list5.resize(5);     // 大小变为5,新元素默认初始化
    list5.resize(2);     // 大小变为2,截断后面的元素

    //5.squeeze释放多余内存  QT6 List才新增的
    qDebug()<<"resize:"<<list5.size();
    list5.squeeze(); // 将容量调整为实际大小
    
  	capacity容量 vs size大小
     *               size    capacity容量
     * reserve(50)	预订了50间房	0人入住	50间房可用
        resize(50)	开了50间房并住满	50人入住	50间房
        append(1)	1人入住,还有49间空房	1人入住	50间房
                       作用               使用场景
    **reserve(n)  	预分配 capacity	已知元素数量,优化性能
    ** resize(n)  	设置size并初始化	需要立即访问 n 个元素
    ** append()  	增加size并添加值	逐个添加元素
    ** size()   	获取实际元素个数  	遍历、检查是否为空

8.迭代器

cpp 复制代码
    //1.遍历下标
    qDebug()<<"list1:"<<list1.size();
    for(int i = 0; i< list2.size();i++)
        qDebug()<<"list2:"<<list2[i];
    //2.范围for遍历
    for(const int &i:list3)
        qDebug()<<"list3:"<<i;
    //3.STL风格迭代器
    QList<int>::iterator it;
    for(it = list4.begin();it!=list4.end();it++)
    {
        *it = *it - 100;//可以修改元素
        qDebug()<<"list4 it:"<<*it;
    }

9.转换

cpp 复制代码
    QList<int>numbers1 = {1,2,3,6,8,99,90};
    //tovector转换为QVector
    QVector<int>vector = numbers1.toVector();
    //或者直接比较内存地址看是否转换成功
    bool success = (numbers1.size() == vector.size());
    qDebug()<<"success1:"<<success;
    for (int i = 0; success && i < numbers1.size(); ++i) {
        success = (numbers1.at(i) == vector.at(i));
    }
   qDebug()<<"success2:"<<success;
    //formvector 从QVector 转换
    QList<int> newList = QList<int>::fromVector(vector);
    qDebug()<<"formvector:"<<(newList == numbers1);
    // toStdList - 转换为 std::list
    std::list<int> stdList(numbers1.begin(), numbers1.end());
    std::list<int>::iterator it1;
    for(it1=stdList.begin();it1!=stdList.end();it1++)
        qDebug()<<"stdList:"<<*it1;

四、QList的隐式共享:

QList本身是一个容器,它实现了隐式共享。这意味着当我们将一个QList赋值给另一个QList时,它们共享同一份数据,直到其中一个需要修改(写操作)时,才会进行深拷贝。

cpp 复制代码
    QList<int> list1 = {1, 2, 3, 4, 5};
    //浅拷贝 - 共享数据
    QList<int> list2 = list1;
    qDebug() << "list1 地址:" << &list1 << "数据地址:"
             << (list1.isEmpty() ? nullptr : &list1[0]);
    qDebug() << "list2 地址:" << &list2 << "数据地址:"
             << (list2.isEmpty() ? nullptr : &list2[0]);
    // 修改 list2,触发写时复制
    list2.append(6);
    // 数据地址现在不同了
    if (!list1.isEmpty() && !list2.isEmpty()) {
        qDebug() << "list1 数据地址:" << &list1[0];
        qDebug() << "list2 数据地址:" << &list2[0];
    }
//打印信息
list1 地址: 0x2d837cf508 数据地址: 0x1fa1e205210
list2 地址: 0x2d837cf500 数据地址: 0x1fa1e203f10
//修改后
list1 数据地址: 0x1fa1e205210
list2 数据地址: 0x1fa1e1d6350

五、参考文档:
QList 类官方文档
Qt QList使用总结

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能15 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G15 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt