简单来讲,map就是一个元素为(key,value)的容器,map最常用的就是用来做相关数据的统计。在Java中有如下几种Map的实现,以及其具体使用场景。
-
Map+Hash =
HashMap(异步,key\value可为null)
HashTable(同步,key\value不能为null)
时间复杂度:按Key增删改查-O(1) ,无序>>>>按Value增删改查O(n)
使用场景:快速定位 -
Map+LinkList+Hash = LinkedHashMap
保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
时间复杂度:按Key增删改查-O(1) ,按Value增删改查O(n),按插入先后排序
使用场景:顺序遍历和快速定位。比如要实现数据库里面O(1)时间的数据查找功能而且还必须支持顺序查找的机制。或者实现配置顺序读取,需要按照读取的顺序访问,而且还需要根据值key直接获取配置内容。 -
Map+RBTree(红黑树) = TreeMap
能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。由于没有使用Hash,所以其无法实现按Key快速查找。
时间复杂度:(按Key或value均可)增删改查-O(log(n)) ,有序>>>value极值查找O(1)
使用场景:统计排序。比如要实现统计各个网站的点击率,并按大小进行排序。 -
Map+Hash+Heap:
这种组合的数据结构没有现成的实现,只能根据需要自己实现。Hash决定了可以实现O(1)的key查找,Heap决定了可以实现O(1)的value极值查找。这样就做到了按key和value的兼顾。
实现思路:HashMap记录Entry在Heap中的index,Heap用数组来实现-——HashMap(key,index)----Heap[index]=Value。可以通过index直接获得Value,也可以直接按Key操作Entry(O(log(n))),也可以通过Heap按Value迅速取得极值Entry。
时间复杂度:
按key增删改查-O(1)
按value 增-O(log(n))(用在Heap的调整上)查(极值-O(1) 普通值-O(n) )删(极值-O(log(n)) 普通值-O(n+log(n)))(用在Heap的调整上)
和上面的TreeMap相比,增加了按Key的快速查找功能,牺牲了普通Value的查找速度。
使用场景:统计TopK,快速定位。比如要实现动态TopK,如实现统计各个网站的点击率,并实时监听点击率排名在前K个的网站。