Java集合—Map
简介
接口中定义的方法:

Map中还包括一个内部类Entry,该类封装了一个key-value对。Entry包含如下三个方法:

实现类
- HashMap类:HashMap是实现了Map接口的key-value集合,实现了所有map的操作,允许key和value为null,它相当于Hashtable,与之存在的区别是hashMap不是线程安全的,HashMap允许null值。
- TreeMap类:TreeMap是基于红黑树的实现,也是记录了key-value的映射关系,该映射根据key的自然排序进行排序或者根据构造方法中传入的比较器进行排序,也就是说TreeMap是有序的key-value集合
- Hashtable类:它是类似与HashMap的key-value的哈希表,不允许key-value为NULL值,另外一点值得注意的是Hashtable是线程安全的

对比
虽然HashMap、Hashtable、TreeMap这三个都是Map接口的实现,其内部实现及性能等还是存在区别。
基本
- HashMap:初始化容量为16,扩容每次为2*oldCap,key和value可以为NULL值
- Hashtable:初始化容量为11,扩容每次为2*oldCap+1,key和value不可以为NULL值
- TreeMap:初始化容量为0,内部是红黑树结构,不存在hash冲突的情况,不存在扩容的操作,key和value不可以为NULL值
Key相等判断标准
- HashMap:两个key通过equals()方法比较返回true,并且两个key的hashCode值也相等
- Hashtable:两个key通过equals()方法比较返回true,并且两个key的hashCode值也相等
- TreeMap:两个key通过compareTo()方法返回0
内部原理
- HashMap:HashMap是散列表实现,内部是数组+链表或者红黑树的结构
- Hashtable:Hashtable也是散列表实现,内部是数组+链表的结构
- TreeMap:TreeMap内部是红黑树的结构
线程安全
- HashMap:不是线程安全的,其实通过Map m = Collections.synchronizeMap(hashMap)的方式也可以使得HashMap变成线程安全的,但是这样做对程序的性能可能是噩梦,在后面会介绍ConcurrentHashMap,建议在多线程的情况下可以使用ConcurrentHashMap替换HashMap.
- Hashtable:是线程安全的,内部方法使用关键字synchronized修饰
- TreeMap:不是线程安全的
这里的Hashtable属于同步容器,还有更多的并发容器可以使用,请参考:Java学习笔记—多线程(同步容器和并发容器)
性能分析
按照如下代码对HashMap、Hashtable、TreeMap的性能进行测试
public class HashMapProgress {
//定义用于测试的HashMap
private static HashMap<Integer,Integer> hashMap = new HashMap<>();
//定义用于测试的Hashtable
private static Hashtable<Integer,Integer> hashtable = new Hashtable<>();
//定义用于测试的TreeMap
private static TreeMap<Integer,Integer> treeMap = new TreeMap<>();
/**
* 添加元素的方法
* @param map 对应的map
* @param count 添加个数
*/
public static void addEntry(Map<Integer,Integer> map, int count){
Long startTime = System.currentTimeMillis();
if (count <= 0){
return;
}
for (int i = 0; i < count; i++) {
map.put(i,i);
}
Long endTime = System.currentTimeMillis();
System.out.println("添加(" + count + ")个元素使用时间:" + (endTime - startTime) + "s");
}
/**
* 获取元素的方法
* @param map
* @param count
*/
public static void getEntry(Map<Integer,Integer> map, int count){
Long startTime = System.currentTimeMillis();
if (count <= 0){
return;
}
for (int i = 0; i < count; i++) {
map.get(i);
}
Long endTime = System.currentTimeMillis();
System.out.println("获取(" + count + ")个元素使用时间:" + (endTime - startTime) + "s");
}
public static void main(String[] args){
System.out.println("-------HashMap测试开始-----");
addEntry(hashMap,1000000);
getEntry(hashMap,1000000);
System.out.println("-------HashMap测试结束-----");
System.out.println("-------Hashtable测试开始-----");
addEntry(hashtable,1000000);
getEntry(hashtable,1000000);
System.out.println("-------Hashtable测试结束-----");
System.out.println("-------TreeMap测试开始-----");
addEntry(treeMap,1000000);
getEntry(treeMap,1000000);
System.out.println("-------TreeMap测试结束-----");
}
}
分别测试了100000,1000000,10000000个数据的情况,测试结果如下所示:
| 数据量 | HashMap | Hashtable | TreeMap |
|---|---|---|---|
| 100000 | 插入用时:18s 查询用时:9s | 插入用时:14s 查询用时:5s | 插入用时:33s 查询用时:17s |
| 1000000 | 插入用时:98s 查询用时:20s | 插入用时:625s 查询用时:31s | 插入用时:242s 查询用时: 145s |
| 10000000 | 插入用时:9773s 查询用时:811s | 插入用时:15055s 查询用时:3369s | 插入用时:22354s 查询用时: 3889s |
通过上表可以看出随着数据量的增加,时间变化差异还是很大的,而在单线程的情况下还是尽量使用HashMap,相对于Hashtable、TreeMap性能更好,而针对特定的情况需视情况而论。
Java集合—Map的更多相关文章
- Java集合Map接口与Map.Entry学习
Java集合Map接口与Map.Entry学习 Map接口不是Collection接口的继承.Map接口用于维护键/值对(key/value pairs).该接口描述了从不重复的键到值的映射. (1) ...
- Java集合——Map接口
1.定义 Map用于保存存在映射关系<key,value>的数据.其中,key值不能重复(使用equals()方法比较),value值可以重复 2.方法 V put(key,value) ...
- Java集合Map基本方法
jdk1.7 api中的方法摘要: 参考java集合大全图:https://www.cnblogs.com/xkzhangsanx/p/10889114.html Map为所有Map子类的接口.
- java集合——Map
声明:以下内容都是来自网络总结,将会参考很多,没有声明转载来源. 一.Map接口 1.HashMap HashMap和HashTable的区别:http://blog.csdn.net/shohoku ...
- Java集合--Map总结
转载请注明出处:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=3311126 第1部分 Map概括 (01) Map ...
- Java集合-----Map详解
Map与Collection并列存在.用于保存具有映射关系的数据:Key-Value Map 中的 key 和 value 都可以是任何引用类型的数据 Map 中的 ...
- Java集合Map与其子类回顾
接10月12号昨天的笔记,今天继续回顾集合中的Map集合. 一.集合工具操作类Collections 问题:collection和collections的区别? 1.collection是单列集合的顶 ...
- Java集合----Map集合
Map Map 用于保存具有映射关系的数据,因此 Map 集合里保存着两组值,一组值用于保存 Map 里的 Key,另外一组用于保存 Map 里的 Value Map 中的 key 和 value 都 ...
- Java 集合-Map接口和三个子类实现
2017-10-31 22:05:59 Map 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值. HashMap是基于散列表实现的,插入.删除和定位元素时间复杂度平均能达到O ...
随机推荐
- php -- PDO异常处理
异常处理: PHP:默认为直接报错 MYSQL:默认为静默模式,错就错,不报错 PDO:默认为静默模式,错就错,不报错 以前,当PHP碰到错误的时候,会直接报错,错误处理会变得相当麻烦.后来,当错误发 ...
- 【BZOJ】1685: [Usaco2005 Oct]Allowance 津贴(贪心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1685 由于每个小的都能整除大的,那么我们在取完大的以后(不超过c)后,再取一个最小的数来补充,可以证 ...
- redhat7搭建本地yum仓库
ftp服务器搭建 安装vsftpd yum install vsftpd 配置启动服务和防火墙 修改配置,由于默认不开启主动模式,需要配置开启,在/etc/vsftpd/vsftpd.conf添加如下 ...
- 动态向SqlParameter 里添加相应参数
先定义一个List,然后再往List里面添加SqlParameter对象,然后将List转为SqlParameter数组即可 List<SqlParameter> ilistStr = n ...
- php计算数组相同值出现次数的代码(array_count_values)
php计算数组相同值出现次数,可以使用php自带函数array_count_values : 说明 array array_count_values ( array $input )array_cou ...
- hrbustoj 1142:围困(计算几何基础题,判断点是否在三角形内)
围困 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 360(138 users) Total Accepted: 157(12 ...
- Socket的三个关联函数
/*lrs_save_param将静态或接收到的缓冲区保存到参数中*/lrs_save_param (char *s_desc, char *buf_desc, char *param_name, i ...
- ChemDraw中化学信息怎么通过Excel搜索
用户可以通过ChemDraw for Excel插件功能在Office Excel中建立ChemOffice菜单将ChemOffice和Excel结合使用,使用电子表格的最大优势之一就是可以清晰查看并 ...
- 那些在BAE上部署node.js碰到的坑
在BAE上使用node.js半年多了,其中碰到了不少因为BAE云环境限制碰到的坑 写下来大家碰到了,也不用那么麻烦的去看好几天代码了,直接对症下药 官方公布的坑有: BAE是使用package.jso ...
- JBPM4 经常使用表结构及其说明
首先我想说.这不一篇原创博文. 这里设置成原创.主要是为了分享,由于它对于jbpm的刚開始学习的人,真的值得一看.原作者的博文地址并没有查到,我是在还有一位转载此文的博主那儿获得的.地址在这儿. 本文 ...