散列表的基本原理和实现
对于基于散列表实现的符号表,若我们要在其中查找一个键,需要进行以下步骤:
1、首先我们使用散列函数将给定键转化为一个“数组的索引”,理想情况下,不同的key会被转为不同的索引,但在实际应用中我们会遇到不同的键转为相同的索引的情况,这种情况叫做碰撞。解决碰撞的方法我们后面会具体介绍。
2、得到了索引后,我们就可以像访问数组一样,通过这个索引访问到相应的键值对。
以上就是散列表的核心思想,散列表是时空权衡的经典例子。
当我们的空间无限大时,我们可以直接使用一个很大的数组来保存键值对,并用key作为数组索引,因为空间不受限,所以我们的键的取值可以无穷大,因此查找任何键都只需进行一次普通的数组访问。
反过来,若对查找操作没有任何时间限制,我们就可以直接使用链表来保存所有键值对,这样把空间的使用降到了最低,但查找时只能顺序查找。在实际的应用中,我们的时间和空间都是有限的,所以我们必须在两者之间做出权衡,散列表就在时间和空间的使用上找到了一个很好的平衡点。
散列表的一个优势在于我们只需调整散列算法的相应参数而无需对其他部分的代码做任何修改就能够在时间和空间的权衡上做出策略调整。
class R
{
int count;
public R(int count){
this.count = count;
}
public String toString(){
return "R[count:" + count + "]";
}
public boolean equals(Object obj){
if(this == obj)
return true;
if (obj != null && obj.getClass() == R.class) {
R r = (R)obj;
if (r.count == this.count) {
return true;
}
}
return false;
}
public int hashCode(){
return this.count;
}
}
对于集合中的所有元素 e
boolean contains(Object o){
return (o==null ? e==null : o.equals(e));
}
如果o为null,--〉如果e为null,返回为true,否则false
如果o不为null,--〉则返回o.equals(e)-->也就是如果o和e对象equal,返回true,否则false
getClass()相关
(在重写equals()方法中用到),还有反射机制的介绍(没看还)
http://blog.csdn.net/Ghost_T/article/details/5811974
Set的源码分析
http://blog.csdn.net/lcore/article/details/8878893
hashCode()相关 讲得很易懂啦
http://blog.csdn.net/lcore/article/details/8885022
关于HashMap的源码分析 也讲得不错
http://blog.csdn.net/lcore/article/details/8885961
Collection源码学习
http://blog.csdn.net/lcore/article/details/8869937
List ArrayList类的源码学习
http://blog.csdn.net/lcore/article/details/8872565
感觉博主这个系列做的很不错啦 20篇都值得去看下