HashMap相关问题(内部数据结构,允许空键空值,影响性能的参数,1.8中有哪些优化,线程安全方面有什么问题,为什么1.8用红黑树,和HashTable区别,和TreeMap、LindedHa区别)

HashMap的内部数据结构是什么

-数组+链表/红黑树

HashMap允许空键空值吗?

  • HashMap最多只允许一个键为Null(多条会覆盖),但允许多个值为Null

影响HashMap性能的重要参数

  • 初试容量:创建哈希表时桶的数量,默认为16
  • 负载因子:哈希表在其通量自动增加之前可以达到多满的一种尺度,默认为0.75

1.8中做了哪些优化?

  • 数组+链表改成了数组+链表或红黑树
  • 链表的插入方式从头插法改成了尾插法
  • 扩容的时候1.7需要对原数组中的元素进行重新hash定位在新数组的位置,1.8先进行插入,插入完成在判断是否需要扩容

HashMap线程安全方面会出现什么问题

  • 在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失
  • 在jdk1.8中,在多线程环境下,会发生数据覆盖的情况

为什么1.8该用红黑树

  • 比如某些人通过找到你的hash碰撞值,来让你的HashMap不断的产生碰撞,那么相同key位置的链表就会不断增长,当你需要对这个HashMap的相应位置进行查询的时候,就回去循环遍历这个超级大的链表,性能很低下。java1.8使用红黑树来来代替超过8个节点数的链表后,查询方式性能的得到了很好的提升从原来的是O(n)到O(longn)

HashMap和HashTable的区别

Hashtable是基于陈旧的Dictionary类的,HashMap是JAVA 1.2引进的Map接口的一个实现,他们都是集合中将数据无序存放的

1、HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法

HashTable Synchronize同步的,线程安全,HashMap不允许空键值为空,效率低。HashMap非Synchronize线程同步的,线程不安全,HashMap允许空键值为空,效率高。 Hashtable是基于陈旧的Dictionary类的,HashMap是JAVA 1.2引进的Map接口的一个实现,他们都是集合中将数据无序存放的。

Hashtable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就想Vector和ArrayList一样。

查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有public方法声明中都有synchronized关键字,而HashMap的源代码中则脸synchronized的影子都没有,当时注释除外。

2、Hashtable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)

3、两者的遍历方式大同小异,Hashtable仅仅比HashMap第一个elements方法

Hashtable table = new Hashtable();
table.put("key","value");
enueration em = table.elements();
while(em.hasMoreElements()){
	String obj = (String)em.nextElement();
	System.out.println(obj);
}

4、Hashtable使用Enumeration,HashMap使用lterator
从内部机制实现上的区别如下:

1.哈希值的使用不同,Hashtable直接使用对象的hashCode

int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF)%tab.length;

而HashMap重新计算hash值,而且用与代替求模:

int hash = hash(k);
int i = indexFor(hash,table.length);

static int hash(Object x){
	int h = x.hashCode();
	
	h +=~(h << 9);
	h ^=(h >>> 14);
	h += (h << 4);
	h ^=(h >>> 10)}
static int indexFor(int h, int length){
	return h &(length-1);
}

2.Hashtable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

TreeMap、HashMap、LindedHashMap的区别

LinkedHashMap 可以保证HashMap集合有序,存入的顺序和取出的顺序一致

TreeMap 实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用lterator遍历TreeMap时,得到的记录是排过序的。

HashMap 不保证顺序,即为无序的,具有很快的访问速度。HashMap 最多只允许一条记录的键为Null;允许多条记录的值为Null。HashMap 不支持线程的同步。

我们在开发的过程中使用HashMap比较多,在Map中插入,删除和定位元素,HashMap是最好的选择。

但如果你要按自然顺序或自定义顺序遍历,那么TreeMap会更好

如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值