HashMap与Hashtable

记录一下这两者的区别:

1.继承关系

 

从图片中可以发现,HashMap继承了AbstractMap,Hashtable继承了Dictionary,两者继承的父类不同。还可以发现,两者都实现了Map,Cloneable,Serializable这三个接口。

2.Key和Value是否支持null

先看Hashtable

 

 源码的注释写着key和value都不能为空。

再看HashMap

 

 

 从注释可以看出key和value都可以为null;value可以与key值相关联,或者null,如果没有key的映射,可以返回null如果key或者value为null。

3.是否线程安全

HashMap是线程不安全的,Hashtable是线程安全的

 

 

 这张图片是Hashtable的put方法,使用了synchronize修饰,Hashtable源码中还有许多方法使用了synchronize修饰来保证线程安全。

4.初始大小与扩容策略

Hashtable的初始大小是11,HashMap的初始大小是16

Hashtable的扩容策略是2n+1(原大小的2倍+1),HashMap的扩容策略是2n(原大小的2倍)。

5.底层数据结构(JDK1.8)

HashMap:

当hash冲突小于8时采用链表法存储,

当hash冲突大于8时采用红黑树存储,

当hash冲突小于6时转化为链表法存储,

原因之一:当hash冲突=8时,链表法的平均查询次数为n/2=4,红黑树的平均查询次数为logn=3,这时将链表存储结构转化为红黑树存储才有意义。

Hashtable:

始终链表方式存储。

6.方法

 1 import java.util.*;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         HashMap<String,String> hashMap = new HashMap<>();
 6         Hashtable<String,String> hashtable = new Hashtable<>();
 7         hashtable.put("Redis","端口6379");
 8         hashMap.put("time","时间会给我答案吗?");
 9 
10         System.out.println(hashtable.get("Redis"));//端口6379
11         System.out.println(hashtable.contains("端口6379"));//true
12         System.out.println(hashtable.containsValue("端口6379"));//true 等价于contains
13         /**
14          * public boolean containsValue(Object value) {
15          *     return contains(value);
16          *}
17          */
18         System.out.println(hashtable.containsKey("Redis"));//true
19 
20         System.out.println(hashMap.get("time"));//时间会给我答案吗?
21         System.out.println(hashMap.containsValue("时间会给我答案吗?"));//true
22         System.out.println(hashMap.containsKey("time"));//true
23         System.out.println(hashMap.put("nu",null));//true
24     }
25 }
Test

发现看出Hashtable有contains方法,HashMap则没有

posted @ 2020-09-24 18:23  雨下_整夜  阅读(402)  评论(0)    收藏  举报