Hash与手写HashMap

Hash(散列函数)

定义

它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法。顾名思义,该数据结构可以理解为一个线性表,但是其中的元素不是紧密排列的,而是可能存在空隙。

一个好的Hash函数应满足下列要求:

正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。
逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。
输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。
冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

常用的Hash算法

MD4,MD5(被破解了)
SHA-1(被破解了),SHA-256,SHA-224,SHA-512,SHA-384

作用

比如你需要上传一个文件,先把这个文件通过hash算法计算出一个 hash 值,然后去和已有的文件进行碰撞,如果已经上传了一样的文件,则不需要上传文件流,直接成功了。

手写HashMap(简易版)

思路

  1. 我们先定义个存储K-V的类,在定义这个类的数组,初始长度16(jdk源码的HashMap就是16)
  2. 将key值通过hash算法计算出 hash 值(小于数组长度),然后这个hash值就是数组的上的位置
  3. 由于我们定义的hash算法会出现碰撞,当出现碰撞时,这里用链的方式做处理
  4. 具体代码如下,此处为了方便测试,因此把数组的长度设置成了2
public class MyHashMap<K, V> {
	private Entry<K, V>[] entrys;
	    private static final Integer initLen = 2;
	    public Integer size = 0;
	
	    class Entry<K, V> {
	        public K k;
	        public V v;
	        public Entry<K, V> next;
	
	        public Entry(K k, V v, Entry<K, V> next) {
	            this.k = k;
	            this.v = v;
	            this.next = next;
	        }
	
	        public K getKey() {
	            return k;
	        }
	
	        public V getValue() {
	            return v;
	        }
	    }
	
	    public void put(K k, V v) {
	        if(entrys==null){
	            entrys  = new Entry[initLen];
	        }
	        Integer index = hash(k) % entrys.length;
	        //处理相同的k所对应的v
	        for(Entry<K,V> entry = entrys[index];entry!=null; entry = entry.next){
	            if(entry.getKey().equals(k)){
	                entry.v = v;
	                return;
	            }
	        }
	        addEntry(k, v, index);
	    }
	
	    public V get(K k) {
	        Integer index = hash(k) % entrys.length;
	        for(Entry<K,V> entry = entrys[index];entry!=null; entry = entry.next){
	            if(entry.getKey().equals(k)){
	                return entry.getValue();
	            }
	        }
	        return null;
	    }
	
	    private void addEntry(K k, V v, Integer index) {
	        entrys[index] = new Entry<K, V>(k, v, entrys[index]);
	        size++;
	    }
	
	    private Integer hash(K k) {
	        return k.hashCode();
	    }
	
	    public static void main(String[] args) {
	        MyHashMap<String, String> m = new MyHashMap<String, String>();
	        m.put("a","1");
	        m.put("b","2");
	        m.put("c","3");
	        m.put("b","4");
	        System.out.println(m.get("a"));
	        System.out.println(m.get("b"));
	        System.out.println(m.get("c"));
	    }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值