map与hash_map使用与对比

#include <iostream>
#include <functional>
#include <map>
#include <ext/hash_map>
#include <string>
using std::string;

struct SInfo
{
    string id_;
    string name_;
    SInfo(string id, string name):id_(id),name_(name){}
};

// map example
template<class T1>
struct SLessThan : public std::binary_function<T1, T1, bool>
{
    bool operator()(const T1 &first, const T1 &second) const
    {
        return first.id_ < second.id_;
    }
};

void testmap()
{
    std::cout<<"------------------- test map ----------------------------"<<std::endl;
    typedef std::map<SInfo, string, SLessThan<SInfo> > Info2IDMap;
    Info2IDMap info2IDMap;
    info2IDMap.insert(std::make_pair(SInfo("1001", "zhangsan"), "1001"));
    info2IDMap.insert(std::make_pair(SInfo("1004", "lisi"), "1004"));
    info2IDMap[SInfo("1003", "wanger")] = "1003";

    for(Info2IDMap::iterator iter = info2IDMap.begin(); iter != info2IDMap.end(); ++iter)
    {
        std::cout<<iter->second<<";";
    }
    std::cout<<std::endl;
}

// hash_map example
typedef struct SHashInfo
{
    size_t operator()(const SInfo &info) const
    {
        unsigned long __h = 0; 
        for (size_t i = 0 ; i < info.id_.size() ; i ++) 
            __h = 5*__h + info.id_[i];
        return size_t(__h);
    }
}SHashInfo;

template<class T1>
struct SEqual : public std::unary_function<T1, bool>
{
    bool operator()(const T1 &first, const T1 &second) const
    {
        return first.id_ == second.id_;
    }
};

void testhashmap()
{
    std::cout<<"-------------------- test hash map -----------------------------"<<std::endl;
    typedef __gnu_cxx::hash_map< SInfo, string, SHashInfo, SEqual<SInfo> > Info2IDMap;
    Info2IDMap info2IDMap(11);
    info2IDMap[SInfo("10086", "beijing")] = "10086";
    info2IDMap[SInfo("10085", "shanghai")] = "10085";
    info2IDMap[SInfo("10087", "tianjin")] = "10087";

    for(Info2IDMap::iterator iter = info2IDMap.begin(); iter != info2IDMap.end(); ++iter)
    {
        std::cout<<iter->second<<";"<<std::endl;
    }
    std::cout<<std::endl;
}

int main(int argc, char *argv[])
{
    testmap();
    testhashmap();

    return 0;
}

通过上面的例子会发现:

1. map需要指定小于函数(可使用默认配置)。

2. hash_map需要指定哈希函数和等于函数。其中针对普通类型有通用配置。

3. hash_map还未被列入标准库中。

4. map的底层使用的是红黑树,因此可以保证数据有序,而hash_map的底层使用的是哈希表,不能保证数据有序。

 

疑问:map和hash_map的使用如何选择?

当数据量很大且hash冲突比较小,数据增删比较少,关心查询性能时使用hash_map;

增删数据较多的情况下使用map。

具体使用还需要根据具体场景判断,主要考虑:数据量,查询速度,内存占用(要注意对象构造速度,hash_map的慢)。

 

posted on 2017-02-25 16:54  霏霏暮雨  阅读(745)  评论(0编辑  收藏  举报

导航