1、关键字是整数时,直接把关键字作为索引
public class Info {
private int key;
private String value;
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Info(int key,String value)
{
this.key=key;
this.value =value;
}
}
public class HashTable {
private Info[]arr;
public HashTable()
{
arr=new Info[100];
}
public HashTable(int maxsize)
{
arr=new Info[maxsize];
}
//插入数据
public void insert(Info info)
{
int key=info.getKey();
arr[key]=info;
}
//获取数据
public Info find(int key)
{
return arr[key];
}
}
public class HashTableTest {
public static void main(String[] args) {
HashTable ht=new HashTable();
ht.insert(new Info(1,"张三"));
ht.insert(new Info(2,"李四"));
ht.insert(new Info(3,"王五"));
System.out.println(ht.find(2).getValue());
}
}
2、关键字是String时,需要用到hashCode()方法
public class Info {
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey( String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Info( String key,String value)
{
this.key=key;
this.value =value;
}
}
public class HashTable {
private Info[]arr;
public HashTable()
{
arr=new Info[100];
}
public HashTable(int maxsize)
{
arr=new Info[maxsize];
}
//插入数据
public void insert(Info info)
{
String key=info.getKey();
arr[hashCode(key)]=info;
}
//获取数据
public Info find(String key)
{
return arr[hashCode(key)];
}
public int hashCode(String key)
{
int hashVal=0;
for(int i=key.length()-1;i>=0;i--)
{
int ch=key.charAt(i);
hashVal+=ch-96;
}
return hashVal;
}
}
public class HashTableTest {
public static void main(String[] args) {
HashTable ht=new HashTable();
ht.insert(new Info("zh","张三"));
ht.insert(new Info("li","李四"));
ht.insert(new Info("wa","王五"));
System.out.println(ht.find("wa").getValue());
}
}
3、这样将字母转换为ASCII码再相加,得到的索引值很容易重复,abc,bbb,cba,最后只存入“王五”,改进一下,用幂的连乘
public int hashCode(String key)
{
int hashVal=0;
int pow27=1;
for(int i=key.length()-1;i>=0;i--)
{
int ch=key.charAt(i);
hashVal+=(ch-96)*pow27;
pow27*=27;
}
return hashVal;
}
4、但是当索引值太大时会出现下标越界,可以通过取模压缩可选值return hashVal%arr.length;
5、当索引值的字符串比较长的时候,hashVal+=(ch-96)*pow27;计算出的值会超出int的范围
BigInteger hashVal=new BigInteger("0");
BigInteger pow27=new BigInteger("1");
for(int i=key.length()-1;i>=0;i--)
{
int ch=key.charAt(i);
BigInteger ch2=new BigInteger(String.valueOf(ch));
hashVal=hashVal.add(ch2.multiply(pow27));
pow27=pow27.multiply(new BigInteger(String.valueOf(27)));
}
return hashVal.mod(new BigInteger(String.valueOf(arr.length))).intValue();
6、压缩后仍然会出现问题,冲突,不能保证每个单词都映射到数组的空白单元
可以通过开放定址法和链地址法