一、自定义字符串的hashcode
如下是Java API提供的String的hashcode生成办法;
s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1], s[0] 表示第一位字符,n表示字符串的长度。
本练习并不是要求去理解这个算法,而是自定义一个简单的hashcode算法,计算任意字符串的hashcode,因为String类不能被重写,所以我们通过一个静态方法来返回一个String的HashCode
public static int HashCode(String)
如果字符串长度是0,则返回0。
否则: 获取每一位字符,转换成数字后,相加,最后乘以23
(s[0]+ s[1] + s[2] + s[3]+ s[n-1])*23.
如果值超过了1999,则取2000的余数,保证落在0-1999之间。
如果是负数,则取绝对值。
随机生成长度是2-10的不等的100个字符串,打印用本hashcode获取的值分别是多少
参考代码
package review5.collection;
public class TestString {
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
int len = (int) (Math.random()*8)+2;
char[] c =new char[len];
for(int j = 0; j < len; j++) {
c[j] = (char) (Math.random()*26+97);
}
String str = c.toString();
System.out.println(HashCode(str));
}
}
public static int HashCode(String str) {
int hash = 0;
if(str.length() == 0) return 0;
else {
for(int i = 0;i < str.length(); i++) {
char ch = str.charAt(i);
hash += (int)ch;
}
hash = (hash *23) % 2000;
if(hash < 0) {
hash = 0 - hash;
}
}
return hash;
}
}
二、自定义MyHashMap
根据前面学习的hashcode的原理和自定义hashcode, 设计一个MyHashMap,MyHashMap内部由一个长度是2000的对象数组实现。
设计put(String key,Object value)方法
首先通过上一个自定义字符串的hashcode练习获取到该字符串的hashcode,然后把这个hashcode作为下标,定位到数组的指定位置。
如果该位置没有数据,则把字符串和对象组合成键值对Entry,再创建一个LinkedList,把键值对,放进LinkedList中,最后把LinkedList
保存在这个位置。 如果该位置有数据,一定是一个LinkedList,则把字符串和对象组合成键值对Entry,插入到LinkedList后面。
设计 Object get(String key) 方法
首先通过上一个自定义字符串的hashcode练习获取到该字符串的hashcode,然后把这个hashcode作为下标,定位到数组的指定位置。
如果这个位置没有数据,则返回空
如果这个位置有数据,则挨个比较其中键值对的键-字符串,是否equals,找到匹配的,把键值对的值,返回出去。找不到匹配的,就返回空
参考代码
Entry.java
package review5.collection;
public class Entry {
public Entry(Object key, Object value) {
super();
this.key = key;
this.value = value;
}
public Object key;
public Object value;
@Override
public String toString() {
return "[key=" + key + ", value=" + value + "]";
}
}
MyHashMap.java
package review5.collection;
import java.util.LinkedList;
public class MyHashMap {
Object[] oArr = new Object[2000];
int count = 0;
@SuppressWarnings("unchecked")
public void put(String key, Object value) {
int i = TestString.HashCode(key);
if(oArr[(int) i] == null) {
LinkedList<Entry> li = new LinkedList<>();
li.offer(new Entry(key,value));
oArr[(int)i] = li;
count++;
}else {
((LinkedList<Entry>) oArr[(int)i]).offer(new Entry(key,value));
count++;
}
}
@SuppressWarnings("unchecked")
public Object get(String key) {
int i = TestString.HashCode(key);
if(oArr[i] == null ) {
return null;
}else {
for(Entry e : (LinkedList<Entry>)oArr[i]){
if(e.key.equals(key)) {
return e.value;
}
}
}
return null;
}
public int size() {
return count;
}
public static void main(String[] args) {
MyHashMap myHashMap = new MyHashMap();
for(int i = 0; i < 100; i++) {
myHashMap.put(""+i, new String("String "+i));
}
//插不进
myHashMap.put(""+99, new String("String "+100));
for(int i = 0; i < myHashMap.size();i++) {
System.out.println(myHashMap.get(""+i));
}
}
}