一、摘要

Qt有为我们提供了很多便捷的容器,如何选择称为开发的一大问题。其实,日常开发map/hash/vector就足够了,下面就以上三种容器进行介绍。

容器选择指南:

特性QMapQHash(他是基于QMap)QVector
排序按键排序无序按插入顺序
查找效率O(log n)O(1)O(n)
插入效率O(log n)O(1)O(1) 在末尾,O(n) 在中间
内存使用较高中等较低
适用场景需要有序键值对快速查找,不关心顺序顺序存储,随机访问

二、QMap(底层实现: 基于红黑树的有序关联容器)

需要注意的是虽然QMap是有序的,但这个有序是他自己根据键进行排序的,不是插入顺序

以增删改查为顺序的代码:


    QMap<QString,int> map;
    //插入元素的两种方式
    map.insert("key1",1);
    map.insert("key2",2);
    map["key3"]=3;
    map["key4"]=4;

    //删除元素
    map.remove("key3");

    //修改元素

    auto it1=map.find("key1");//注意find返回的是迭代器
    if(it1!=map.end())
    {
        it1.value()=5;
    }
    //遍历map的两种方式,注意map是有序的
    //1.按照键的升序
    QMapIterator<QString,int> it2(map);
    while(it2.hasNext())
    {
        it2.next();//类似于索引++
        qDebug()<<it2.key()<<": "<<it2.value();
    }
    //2.用C++11的for循环
    for(auto it=map.begin();it!=map.end();it++)
    {
        qDebug()<<it.key()<<": "<<it.value();
    }

   //获取所有的键和值
    QList<QString> keys=map.keys();
    QList<int>  values=map.values();
    for(int i=0;i<keys.size();i++)
    {
        qDebug()<<"键:"<<keys[i];
    }

    for(int i=0;i<values.size();i++)
    {
        qDebug()<<"键:"<<values[i];
    }


结果:

三、QHash(底层实现: 基于哈希表的无序关联容器)

操作和QMap基本相同

代码:

    QHash<QString,int> hash;
    //增
    hash.insert("key1",1);
    hash.insert("key2",2);
    hash["key3"]=3;
    hash["key4"]=4;
    //删
    hash.remove("key2");
    //改、查
    auto it=hash.find("key3");
    if(it!=hash.end())
    {
        it.value()=6;
    }
    //遍历
    for(auto it=hash.begin();it!=hash.end();it++)
    {
        qDebug()<<"键:"<<it.key()<<"值"<<it.value();
    }
   //获取所有键和值
    QList<QString> keys=hash.keys();
    QList<int> values=hash.values();
    for(int i=0;i<keys.size();i++)
    {
        qDebug()<<keys[i];
    }

    for(int i=0;i<values.size();i++)
    {
        qDebug()<<values[i];
    }

结果:

四、Qvector(底层实现: 动态数组,连续内存存储)

就按照C++的数组进行操作就行

代码:

  QVector<int> v;
    //v={1,2,3,2,4,56,4};也可以这样赋值

    //增
    //尾插
    v.append(10);
    v.append(20);
    v.append(30);
    //头插
    v.prepend(5);

    //删
    v.remove(2);//删除索引2处的元素
    v.removeOne(30);//删除第一个值为30的元素

   //改
    v.replace(0,60);//将索引为0的元素改为60
    //v[0]=60效果一样

    //查
     int index=v.indexOf(60);//返回元素索引
      qDebug()<<"60的索引为:"<<index;
    //遍历
     for(auto it=v.begin();it!=v.end();it++)
     {
         qDebug()<<*it;
     }

结果:

算法:

头文件:#include<algorithm>

排序:

代码:

QVector<int> v={5,6,8,455,45,1,8,4,5};
    for(auto it=v.begin();it!=v.end();it++)
    {
        qDebug()<<*it;
    }
    qDebug()<<Qt::endl;
    std::sort(v.begin(),v.end());
    for(auto it=v.begin();it!=v.end();it++)
    {
        qDebug()<<*it;
    }

结果:

vector转换为set

代码:

 QVector<int> v={5,6,8,455,45,1,8,4,5};
    // QVector与其他容器转换
   QSet<int> set(v.begin(), v.end());//注意集合会有一个去重操作
    qDebug()<<set;

结果:

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐