首页 > 代码库 > 《java编程思想》:散列的原理
《java编程思想》:散列的原理
以实现一个简单的HashMap为例,详细讲解在code之中。
简单解释散列原理:
1.map中内建固定大小数组,但是数组并不保存key值本身,而是保存标识key的信息
2.通过key生成数组角标,对应位置存放LinkedList,list中存放的是键值对
3.如此,无论放入多少个键值对,数组大小都不必改变,当key值生成的角标值重复时,获取对应位置的list,向list中添加键值对即可
4.当调用get()方法时,只需遍历对应角标位置的list,而不用遍历所有的键值对信息,所以加快了查询速度。
5.注意,get()和put()中使用的计算散列值,也就是数组角标的公式一定要一致,保证计算所得的角标一致
/** * Created by Don9 on 2017/ */ public class MyHashMap<K,V> extends AbstractMap<K,V>{ /* 1.自定义数组大小 */ static final int SIZE = 999; /* 2.创建内部数组,数组存放的是LinkedList,而list中存放的是想要存放的键值对 */ LinkedList<MyEntry<K,V>>[] buckets = new LinkedList[999]; /* 3.put方法,此方法返回key对应的曾经的oldValue */ public V put(K key,V value){ /* 4.先定义一个返回值 */ V oldValue = null; /* 5.根据key计算出一个散列值,用于当作内置数组的下角标( 此公式不固定,是自定义的,但是要保证结果稳定不变,同时不能大于数组size) */ int index = Math.abs(key.hashCode()) % SIZE; /* 6.当index位置为空时,填充新的list */ if(buckets[index]==null){ buckets[index] = new LinkedList<MyEntry<K,V>>(); } /* 7.获取index位置的list */ LinkedList<MyEntry<K, V>> bucket = buckets[index]; /* 8.MyEntry是自定义的Entry实现类,用于保存键值对,这个类也可以自定义,只要实现接口Entry即可, 新建entry保存传入的键值对 */ MyEntry<K, V> newMe = new MyEntry<K, V>(key,value); /* 9.定义一个found标记,用于记录是否替换完毕 */ boolean found = false; ListIterator<MyEntry<K, V>> it = bucket.listIterator(); /* 10.遍历当前位置的list */ while(it.hasNext()){ MyEntry<K, V> oldMe = it.next(); /* 11.list中已经存在了当前key */ if(oldMe.getKey().equals(key)){ /* 12.获得oldValue值,用于返回 */ oldValue = oldMe.getValue(); /* 13.用新的entry替换老的 */ it.set(newMe); /* 14.标记改为true,说明替换完毕 */ found = true; /* 15.跳出 */ break; } } /* 16.如果未替换完毕,也就是说key值在之前的list中不存在 */ if(!found){ /* 17.添加新的entry到list中 */ bucket.add(newMe); } /* 18.返回oldValue */ return oldValue; } /* 19.定义get查找方法 */ public V get(Object key){ /* 20.生成散列值,也就是数组角标,此处一定要和put方法中生成方式一致,保证相同的key生成相同的位置 */ int index = Math.abs(key.hashCode()) % SIZE; /* 21.index位置为null,不存在key,返回null */ if(buckets[index]==null){ return null; } /* 22.index位置不为null,遍历查询,返回value */ for(MyEntry<K,V> me:buckets[index]){ if(me.getKey().equals(key)){ return me.getValue(); } } return null; } @Override public Set<Entry<K, V>> entrySet() { return null; } }
《java编程思想》:散列的原理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。