Java 之 Map 的实现原理(HashMap,LinkedHashMap,Hashtable)

HashMap的实现原理:

  • 1.基于哈希表(数组+链表+二叉树(红黑树))
  • 2.默认加载因子为0.75,默认数组大小是16,
  • 3.把对象储存到哈希表中,如何存储 ?
  • 把key对象通过hash()方法计算hash值,然后用这个hash值对数组长度取余(默认16)来决定该Key对象
  • 在数组中存储的位置,当这个位置有多个对象时,以链表结构存储,jdk1.8后,当链表长度大于8时,链表将
  • 转换为红黑树结构存储。
  • 目的是为了取值时,提高效率,取值更快
  • 扩充原理:当数组的容量超过了75%,表示该数组需要扩充
  • 扩充的算法是:当前数组容量<<1(右移一位)(相当于*2),扩充一倍;缺点:扩充次数过多,会影响性能,每次扩充表示哈希表重新散列
  • (重新计算每个对象的储存位置),在开发中要尽量减少扩充次数带来的性能问题。
  • 线程不安全,适合在单线程中使用
    LinkedHashMap
    LinkedHashMap是HashMap的子类,由于HashMap不能保证顺序恒久不变,此类使用了一个双重链表来维护元素添加顺序
    Hashtable
    • 基于哈希表实现
    • 默认数值大小为11,加载因子0.75
    • 扩充方式:原数组大小*2+1;原数组大小<<1+1
    • 线程安全的,用在多线程
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Map接口:
 * 1.键值对储存一组对象
 * 2.Key保证唯一,不能重复,Value可以重复
 * 3.具体的实现类:HashMap TreeMap Hashtable LinkedHashMap
 * 
 * HashMap的实现原理:
 * 1.基于哈希表(数组+链表+二叉树(红黑树))
 * 2.默认加载因子为0.75,默认数组大小是16,
 * 3.把对象储存到哈希表中,如何存储 ?
 * 		把key对象通过hash()方法计算hash值,然后用这个hash值对数组长度取余(默认16)来决定该Key对象
 * 	 在数组中存储的位置,当这个位置有多个对象时,以链表结构存储,jdk1.8后,当链表长度大于8时,链表将
 *   转换为红黑树结构存储。
 * 目的是为了取值时,提高效率,取值更快
 * 扩充原理:当数组的容量超过了75%,表示该数组需要扩充
 * 扩充的算法是:当前数组容量<<1(右移一位)(相当于*2),扩充一倍;缺点:扩充次数过多,会影响性能,每次扩充表示哈希表重新散列
 * (重新计算每个对象的储存位置),在开发中要尽量减少扩充次数带来的性能问题。
 * 5.线程不安全,适合在单线程中使用
 * 
 * 
 */
public class MapDemo {
	/**
	 * LinkedHashMap是HashMap的子类,由于HashMap不能保证顺序恒久不变,此类使用了一个双重链表来维护元素添加顺序
	 */
private static void HashMap(){
	Map<String,String> table=new LinkedHashMap<>();
	table.put("one","Lily");
	table.put("two","Tom");
	table.put("three","Bin");
	table.forEach((key,value)->System.out.println(key+"->"+value));
}
	
	
private static void hashtable(){
	/**
	 * 基于哈希表实现
	 * 默认数值大小为11,加载因子0.75
	 * 扩充方式:原数组大小*2+1;原数组大小<<1+1
	 * 线程安全的,用在多线程
	 */
	Map<String,String> table=new Hashtable<>();
	table.put("one","Lily");
	table.put("two","Tom");
	table.put("three","Bin");
	table.forEach((key,value)->System.out.println(key+"->"+value));
}
private static void hashMap(){
	Map<Integer,String> map=new HashMap<>();
	map.put(1, "Tom");
	map.put(2, "Jack");
	map.put(3, "Vince");
	map.put(4, "Bin");
	map.put(5, "Lily");
	map.put(6, "Mack");
	System.out.println("size="+map.size());
	//从Map中取值,通过Map的get方法获取值
	System.out.println(map.get(1));//通过key取value
	
	//map的遍历
	Set<Entry<Integer,String>> entrySet=map.entrySet();
	for(Entry e:entrySet){
		System.out.println(e.getKey()+"->"+e.getValue());
	}
	//System.out.println(map.entrySet());
	//2.遍历键
	System.out.println("-----------------");
	Set<Integer> keys=map.keySet();
	for(Integer i:keys){
		String value=map.get(i);
		System.out.println(i+"->"+value);
	}
	System.out.println("-----------------");
	//3.便利值
	Collection<String> values=map.values();
	for(String s:values){
		System.out.println(s);
	}
	System.out.println("-----------------");
	//4.foreach
	map.forEach((key,value)->System.out.println(key+"->"+value));
	
	//权限
	System.out.println(map.containsKey(6));
	
	//hash
	Integer key=1434;
	System.out.println(1434%16);
}
	public static void main(String[] args) {
		//hashMap();
		hashtable();
		linkedHashMap();
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_44117272/article/details/89644352
今日推荐