优点

     内部维护红黑树,通过键查找值的速度非常快,时间复杂度为log2(n)


包含头文件

#include <iostream>
#include <string>
#include <map>

 

数据的插入

std::map<int, std::string> mapStudent;
//插入数组,数组的下标实际上就是索引
mapStudent[4] = "fengyuzaitu@126.com";

 

数据的遍历

std::map<int, std::string>::iterator iter;
iter = mapStudent.find(5);
//访问不到数据的判断
if (iter == mapStudent.end()) return;

 

数据的删除

std::cout << iter->second << std::endl;
//删除该记录
mapStudent.erase(iter);

注意:
对于容器而言,是否已经遍历完容器数据,是根据iter是否已经迭代到end()

调用erase函数之后,迭代器会失效,需要重新获取新的迭代器指针,进行操作,否则会访问到无效指针


场景1

所有的触发事件(包括告警和抓拍)等等,都会有一个时间戳的唯一标识,64位整型作为map索引,消息体作为值,保存在json里面,每一个客户端访问根据上一次的访问时间戳,获得最新的消息数据。如果采用遍历的方式将非常慢,如果采用upper_bound将会大大降低遍历的时间,其实跟find函数性能一样,只不过是查询大于某一个值的函数操作

说明

map::upper_bound()是C++ STL中的内置函数,该函数返回一个迭代器,该迭代器指向刚好大于k的下一个元素。

用法

map_name.upper_bound(key)

参数:该函数接受单个强制性参数键,该键指定返回其upper_bound的元素。

返回值:该函数返回一个迭代器,该迭代器指向刚好大于k的下一个元素。如果在参数中传递的键超过了容器中的最大键,则迭代器返回最后元素的下一个指针,也就是指向end

例子

int TestMapUpperBound()
{
	std::map<int, int> mp;

	mp.insert({ 12, 30 });
	mp.insert({ 11, 10 });
	mp.insert({ 15, 50 });
	mp.insert({ 14, 40 });

	auto it = mp.upper_bound(11);
	if (it != mp.end())
	{
		std::cout << "The upper bound of key 11 is ";
		std::cout << (*it).first << " " << (*it).second << std::endl;
	}

	it = mp.upper_bound(13);
	if (it != mp.end())
	{
		std::cout << "The upper bound of key 13 is ";
		std::cout << (*it).first << " " << (*it).second << std::endl;
	}

	it = mp.upper_bound(17);
	if (it != mp.end())
	{
		std::cout << "The upper bound of key 17 is ";
		std::cout << (*it).first << " " << (*it).second;
	}

	return 0;
}



 

map中数字的排序策略说明

为了实现快速查找,map内部本身就是按序存储的(例如红黑树),在通过键值对实现查询的时候,就会按照key的大小顺序排序。map默认是从小到大顺序排序,因为map提供了默认的最小比较器

template < class Key, class T, class Compare = less<Key>,

           class Allocator = allocator<pair<const Key,T> > > class map;

因此如果是需要指定从大到小排序,与less相对的是greater:

template <class T> struct greater : binary_function <T,T,bool>

 {  bool operator() (const T& x, const T& y) const    {return x>y;}};

 

排序模板定义不准确出现问题的排查 https://blog.51cto.com/fengyuzaitu/2421991
上述定义了一个排序的模板函数,如果需要指定map元素从大到小排序,调用声明如下: std::map<std::int64_t, std::string, greaterkey<std::int64_t>> mapTestData;
template <class T> struct greaterkey {//用于指定map当中的排序,递减,map中默认递增 bool operator() (const T& x, const T& y) const { if (x == y) return false; return x > y; } }; template <class T> struct lesskey { bool operator() (const T& x, const T& y) const { if (x == y) return false; return x < y; } };


断点迭代器不为end,却通过end检测

由于多线程的缘故,通过了end的检测,说明当时数据是存在的,另外一个线程将其置空,导致当前线程的内容指向了空指针,接下来就是程序抛异常,因此需要加锁,对资源进行保护