JAVA面试题---------- Hashmap,Hashtable,HashSet

1.Hashmap和Hashtable的区别

  • 都实现了Map接口

  • 平时用的多的是Hashmap,因为他效率高,方法没有加sychronaized关键字,所以是线程不安全的,在多线程的使用需要自己加同步。而Hashtable是线程安全的,方法都有同步,所以效率要慢一点

  • HashTable使用Enumeration,HashMap使用Iterator

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

  • 实现机制不同

  • Hashmap源码分析(JDK1.7):

首先我们知道刚入map的值是以一个条目放入,条目包括key,value,在map中自己定义这样一个条目类,里面有key和value属性还有一个int类型的hash值,我们放入元素的时候,如果key值相等,之前的key-->value条目就会被覆盖,判断key相等的方法就是比较当前要加入的entry的key的hash值,hash值相等,认为key重复,如果不重复,会根据计算得到的hash值给出entry的存放地址。


hashmap底层使用一个Entry数组实现的,每一个数值元素又是一个链表,当我们往HashMap中put元素的时候,先根据key的重新计算元素的hashCode,根据hashCode得到这个元素在table数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。往table数组中加入或者查找时,都是根据entry类型的元素的key的hash值进行操作的,这个table数组的初始长度是16,且必须是2的幂次数,扩容是扩为原始大小的2倍。后面会解释这样的原因。


    static final int DEFAULT_INITIAL_CAPACITY = 16;
    transient Entry[] table;

我们知道Object类中有一个hashCode()方法就是返回对象的hash值,但是并没有提供具体的实现,根据对象存放的地址给出hashcode值,那么其他要用hashcode解决冲突确定元素的存放地址的类需要自己提供实现方法,一般就是容器map,list,set中会利用hashcode操作元素的地址,那么为什么不用 Object.equals方法呢?

如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了,那么利用hashcode在集合查找时,就能大大降低对象比较次数,提高查找效率!


那hashmap是如何计算key的hash值的呢?在hashmap里就算hash的值是如下:


到hashcode值h,在找元素的存放地址,下图解释为什么要求table数组的初始长度是2的幂次


  • Hashtable源码分析(JDK1.7): 

与hashmap不同的是初始容量

Hashtable中hash数组默认大小是11,增加的方式是 old*2+1

计算hashcode的方法不同,直接使用对象的hashcode(),也就是Object中的方法

 HashSet

 HashSet实现的是set接口,底部使用HashMap来实现,主要利用HashMap中的key不可重复来实现set不可重复的要求,手写简单的HashSet实现:

package xidian.lili.test;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Scanner;

public class MyHashSet<K> {

	private transient HashMap<K, Object> map;
	private static final Object obj=new Object();
	
	public MyHashSet(){
		map=new HashMap<K, Object>();
	}
	public int size(){
		return map.size();
	}
	public boolean add(K e){
		return map.put(e, obj)==null;
	}
	public boolean remove(K e){
		return map.remove(e)==null;
	}

}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值