散列表、哈希冲突学习记录

407 阅读3分钟
/********************************************
 * All Rights Reserved By www.laughing.ren
 * @author:Laughing_Lz
 * @version:2018年11月27日 上午1:07:01
 * ******************************************/
package ren.laughing.code.Test;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

public class Hash {
	class Son {
		private int age;
		private String name;
	}

	/*
	 * ThreadLocalMap 使用了开放寻址法处理hash冲突 数据量小,装载因子小(较于链表更浪费内存空间)
	 * 开放寻址法的数据都存储在数组中,可以有效利用CPU缓存加快查询,而且序列化较为简单。
	 * 删除数据的时候比较麻烦,需要特殊标记已经删除掉的数据。而且,在开放寻址法中,所有的数据都存储在一个数组中,比起链表法来说,冲突的代价更高。所以,
	 * 使用开放寻址法解决冲突的散列表,装载因子的上限不能太大。这也导致这种方法比链表法更浪费内存空间。
	 */
	public static void hash() {
		// ThreadLocalMap是ThreadLocal的内部类,它是一个Map,key是ThreadLocal的实例变量
		ThreadLocal<Son> threadLocal = new ThreadLocal<Son>();
		// 使用链表法解决hash冲突,适用于大对象,大数据量,装载因子可以大于1,使用灵活,可将链表转换为红黑树、跳表等结构。
		LinkedHashMap<String, Son> linkedHashMap = new LinkedHashMap<>();
		HashMap<String, Son> map = new HashMap<String, Son>();
		// hashmap 可修改初始大小,默认为16,装载因子默认0.75
		HashMap<Object, Object> hashMap = new HashMap<Object, Object>(110);
	}
	/*
	 * 设计工业级的散列表,应具有哪些属性? 1.支持快速查询、插入、删除 2.内存占用合理,不能浪费过多的内存空间
	 * 3.性能稳定,极端情况下,散列表的性能也不会退化到无法接受的情况
	 */

	/*
	 * 如何设计工业级的散列表? 1.设计一个合理的散列函数 2.定义装载因子阈值,并且设计动态扩容策略 3.选择合适的散列冲突解决方法
	 */

	/*
	 * 集合类的带hash的,例如hashmap、hashset、hashtable等。
	 * hashmap中散列函数是key的hashcode与key的hashcode右移16位异或,这是为了把key的高位考虑进去,如果key是0,hash值为0
	 * 。在put的时候,如果表没有初始化,需要初始化下,在计算key的位置的时候很巧妙,使用表的length-1和key的hash值与计算的,
	 * 实际上就是对key的hash值对表长取模,基于hashmap是2的幂次方特性,这种位运算速度更快。如果put后hashmap的数据容量超过了表的容量*
	 * 负载因子,就会自动扩容,默认是两倍,自动扩容方法是将key的hash与表长直接与判断是否有高位,有高位就把这个node放到新表里旧表对应位置加旧表长的地方
	 * 。没有高位就直接是新表旧位置。这是hashmap1.8的处理方法。hashmap1.7还是对key的hash取模。如果是个非常大的数,赋值为integer
	 * .max。hashmap采用的是链地址法结合红黑树解决hash冲突,当桶中链表长度大于8就会将桶中数据结构转化为红黑树。
	 * hashtable默认的初使容量11,负载因子也是0.75,如果要指定初始化hashtable容量最好是给一个素数。
	 * 这是因为放入table的时候需要对表长取模,尽量分散地映射。hashtable通过链地址法解决hash冲突,当数据容量大于数据容量*负载因子自动扩容,
	 * 扩容原表长两倍+1。
	 */
	/*
	 * TreeMap 使用红黑树的数据结构,好好研究源码
	 */
	Map<String, String> map = new TreeMap<>();
}