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可以实现,它还可以按读取顺序来排列