HashMap那些事

来源:互联网 发布:windows samba 编辑:程序博客网 时间:2024/05/22 15:16

1. 什么是hash

它是一个任意长度的二进制值通过一个映射关系(哈希算法---相当于大学里面的学号的一个映射规则)转换成一个固定长度的二进制值(哈希值---相当于我们大学里面的学号)


任意长度的二进制值 和 固定长度的二进制值 是一个一一对应关系
固定长度的二进制值就相当于一个任意长度的二进制值的一个摘要
固定长度的二进制值 相当于一个关键字 key
真正有效的数据 就是这个学员的基本信息,一个任意长度的二进制值 value

key ———— value;
hash 只是确定了一个key和一个value的唯一映射关系


2. hash表

特定:最重要的特定---它存储效率很高,取数据的时间负责读是1 O(1)

hash 通过一个key一个输入,通过一个哈希函数 ,来找到数组中与这个key唯一映射的value
根据这个hash函数 找到 数组中这个value的下标
table aaa = 【】;

int index = hash(key);
int value = aaa【index】;O(n);

3. hash函数

key,找下标,有哪些方法可以找到下标
除留取余数法(取摸)
int index = key%m;

4. hash表处理冲突

1. 线性探测法: 探测的步长是1;
2. 链表形式


HashMap

1、hashmap的put方法
2、hashmap的get方法
3、hashmap的扩容机制
hashmap的初始长度 16,负载因子0.75


代码

public interface MyMap<K, V> {// 定义设置值的方法V put(K key, V value);// 定义取值的方法V get(K key);// 定义获取集合中元素个数的int size();interface Entry<K, V> {K getKey();V getValue();}}

package hashmap;public class MyHashMap<K, V> implements MyMap<K, V> {// 默认长度private static int defaultLength = 16;// 默认负载因子private static double defaultLoad = 0.75;// 数组private Entry<K, V>[] table = null;// size记录数组的元素个数private int size = 0;public MyHashMap() {this(defaultLength, defaultLoad);}public MyHashMap(int defaultLength, double defaultLoad) {this.defaultLength = defaultLength;this.defaultLoad = defaultLoad;table = new Entry[defaultLength];}/** * 定义哈希函数算法计算出key对应于数组中的索引 *  * @param key * @return */private int getIndex(K key) {return key.hashCode() & (defaultLength - 1);}@Overridepublic V put(K key, V value) {// 根据key 利用定义的算法取得对应数组的下标int index = getIndex(key);// 根据这个下标 判断该位置是否有数据Entry<K, V> e = table[index];if (null == e) {// 数组这个索引位置没有元素// 创建entry结构 记录下key,value,index,由于没有下一个元素 所以 next为null// 插入元素table[index] = new Entry<K, V>(key, value, null, index);} else {// 数组这个索引位置有元素// 创建entry结构 next为原来所在元素的引用 这样就把新元素和旧元素连接了起来Entry<K, V> newEntry = new Entry<K, V>(key, value, e, index);table[index] = newEntry;}// 元素个数++size++;return table[index].getValue();}@Overridepublic V get(K key) {// 根据key 利用定义的算法取得对应数组的下标int index = getIndex(key);return table[index] != null ? table[index].getValue() : null;}@Overridepublic int size() {return size;}class Entry<K, V> implements MyMap.Entry<K, V> {private K key;private V value;private Entry<K, V> next;// 记录Entry在数组中的索引位置private int index;public Entry(K key, V value, Entry<K, V> next, int index) {this.key = key;this.value = value;this.next = next;this.index = index;}@Overridepublic K getKey() {return key;}@Overridepublic V getValue() {return value;}}}

以上代码简易的实现了hashmap 但是存在许多问题 比如扩容 key 唯一 并发修改 get方法也存在问题(应当取得所以位置后遍历链表 找到对应的key 取得对应的value)


原创粉丝点击