前段时间学习了哈希表,由于各种原因,直到今天才有时间写博客,现在让我来谈谈我对哈希表的理解。
哈希表是一种数据结构,它可以提供快速的插入和查找操作。不论hash表中有多少数据,插入和删除,都只需要O(1)的时间复杂度。所以如果不需要有序遍历数据,并且可以提前预测数据量的大小,那么使用哈希表往往是方便和快捷的。
使用哈希表时,由于不同的关键字可能得到同一个哈希地址,这种现象称之为冲突。
在诸多大神们的总结下,有以下几种两种常见的方法解决冲突:
1、开放地址法
即发生冲突时,把冲突的数据项放在数组的其他位置
2、链地址法
即在冲突的位置上设置一个链表结构,把冲突的数据项放入其中。但是当数据量非常巨大时,其性能将大大的降低,这就需要给它进行扩容,称之为rehash。
分析完毕,让我们来谈谈代码吧。
(1)插入方法
计算key的hash值,这里调用hashCode()方法来计算hash值;
计算index值,作为table的下标,即table[index]
private int getKey(String id){
int key=id.hashCode();
int index=(key)%(array.legth);
return index;
}
public void add(E e){
int index=getKey(e.getId());
if(array[index]==null){
LinkedList<E> l=new LinkedList<E>();
l.add(e);
array[index]=l;
}else{
array[index].add(e);
}
if((count++)>=threshold){
rehash(2*array.length);
}
}
(2)查找方法
public E get(String id){
int index=getKey(id);
//遍历链表
for(int i=0;i<array[index].size();i++){
if(array[index].element().getId()==id){
E e=array[index].element();
return e;
}
}
return null;
}
(3)删除方法
public void remove(String id){
int index=getKey(id);
for(int i=0;i<array[index].size();i++){
if(array[index].element().getId()==id){
E e=array[index].remove();
}
}
(4)哈希表通用方法演示程序
Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();
for(int i=0;i<=10000000;i++){
numbers.put("hash"+i, i);
}
long time1=System.currentTimeMillis();
Integer n = numbers.get("hash1000000");
long time2=System.currentTimeMillis();
long s = time2-time1;
System.out.println("查询时间为:"+s);
Integer nn = numbers.get("hash88");
if(n != null)
System.out.println(n);
System.out.println(nn);
}
<!--EndFragment-->