我用的是qt,但是这里用的方法qmap却不支持,挺郁闷的。
看到java有现成的linkedhashmap使用,更郁闷。
做项目的时候,从数据库搜索了几万条数据,需要对每条数据处理,然后把处理结果显示。开始用的qmap,map的键值对是地址-其他信息,很快捷方便。但是看显示结果的时候发现,qmap自动排序了,我显示的有时间,但是这里却把地址排序。所以我想实现按照时间排序。
一开始的思路是对qmap或map本身动手脚,但是各处搜索,发现几个思路。
1.重载map的构造函数的第三个参数,有人干脆直接永远返回true。这样的弊端一个是让map快速查询变得没了意义,甚至会在find等调用到比较函数的地方出现错误。先舍弃。
2.有人说用List<pair<string,T> >链表,但是链表本身并不排序,我自己试了一下,本来用map是300~500ms就把数据库查询的数据处理完毕了,用来这种结构时间变成了8s。我不觉得我的用户会有耐心等那么久。
翻看论坛评论的时候,无意看到一个评论让我醍醐灌顶,map设计的意义就是用来排序,加快查询速度的,何必舍本逐末。我所苦苦追求的,对map改动不现实,当你按照插入顺序排序之后,势必改动了map本身的排序算法,那么我这几万条查询数据岂不是又变成8s多!但是如果我把map所有数据拿到之后,想办法按值排序呢!
思路:
1、构造multimap,multimap<QString,ASSOCReqAddrsResult> assocReqAddrListResult;其value是个结构体,在结构体中增加index变量,用于之后的比较。
2、填充map,填充时记得按照增加的顺序把值赋值给index
3、将一对多的map放到vecor容器,vec等容器支持sort或qsort进行自定义比较算法
4、直接调用sort,对map按index排序,即可实现想要的效果。
前面两步十分简单,重点说第三、四步。
map->vector容器:
//把map中元素转存到vector中
vector<SPAIR> vec(assocReqAddrListResult.begin(),assocReqAddrListResult.end());
sort的构造函数如下:
template <class RandomAccessIterator>
void sort ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
qt中有qsort构造函数(ps:帮助索引qsort有个简单的例子)
void qSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan)
都是一个意思,可以对第三个参数传入一个函数地址,实现自定义排序。我的例子如下:
bool cmp(const SPAIR& x,const SPAIR& y){
return x.second.index<y.second.index;
}
这里的vec里的元素是SPAIR,所以我们这里这里的比较对象,应该比较的也是SPAIR。
最后直接调用即可:
sort(vec.begin(),vec.end(),cmp);
测试代码如下:
#include <iostream>
#include "vector"
#include <map>
#include <Qdebug>
#include <algorithm>
class ASSOCReqAddrsResult{
public:
unsigned index;
QString recvTime;//时间
...
bool operator <(ASSOCReqAddrsResult item){return index<item.index;}
};
typedef pair<QString,ASSOCReqAddrsResult> SPAIR;
bool cmp(const SPAIR& x,const SPAIR& y){
return x.second.index<y.second.index;
}
int main(){
multimap<QString,ASSOCReqAddrsResult> assocReqAddrListResult;
ASSOCReqAddrsResult item;
item.index = 0;
item.recvTime = "08:20:22.123";
assocReqAddrListResult.insert(make_pair("11",item));
item.index = 1;
item.recvTime = "08:20:26.124";
assocReqAddrListResult.insert(make_pair("01",item));
item.index = 2;
item.recvTime = "08:20:32.125";
assocReqAddrListResult.insert(make_pair("31",item));
//把map中元素转存到vector中
vector<SPAIR> vec(assocReqAddrListResult.begin(),assocReqAddrListResult.end());
sort(vec.begin(),vec.end(),cmp);
for(int i=0;i<vec.size();i++){
qdebug()<<vec[i].second.recvTime<<","<<vec[i].second.index<<","<<vec[i].first;
}
}