实现一个简单的散列表(HashMap)
下面参考java.util.HashMap<K, V>,写了一个简单的散列表,只实现了其中的put和get方法,使用链接法"碰撞冲突"。代码最后,自定义了一个People类,并覆盖了equals,hashCode,toString方法,实现了Comparable接口。利用People类检验散列表的正确性,并利用Arrays或Collections对People进行排序。
import java.util.Arrays; //import java.util.Collections; class ListNode<K, V> {//为解决"碰撞冲突",使用链接法的结点结构。 ListNode<K, V> next; K key; V val; public ListNode(K k, V v) { key = k; val = v; } } class HashMap<K, V> {//一个简单的散列表,实现了put和get方法。 ListNode<K, V>[] table = null; //构造一个散列表:一个存放链表的数组。 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //16 int size; public HashMap() { setUp(DEFAULT_INITIAL_CAPACITY); } public HashMap(int capacity) { setUp(capacity); } @SuppressWarnings("unchecked") public void setUp(int capacity) { size = capacity; table = (ListNode<K, V>[])new ListNode[size]; } public int hash(Object k) { //散列函数 return Math.abs(k.hashCode() % table.length); } public V put(K key, V value) { //return the old value if(key == null) return putForNullKey(value); int i = hash(key); for(ListNode<K, V> e = table[i]; e != null; e = e.next) { if(e.key == key || key.equals(e.key)) { V oldVal = e.val; e.val = value; return oldVal; } } addListNode(i, key, value); return null; } public V putForNullKey(V value) { for (ListNode<K, V> e = table[0]; e != null; e = e.next) { // 只考虑table中下标为0的位置。 if(e.key == null) { V oldVal = e.val; e.val = value; return oldVal; } } table[0] = new ListNode<>(null, value); return null; } public V get(K key) { if(key == null) return getForNullKey(); int i = hash(key); for(ListNode<K, V> e = table[i]; e != null; e = e.next) { if(e.key == key || key.equals(e.key)) return e.val; } return null; } public V getForNullKey() { for(ListNode<K, V> e = table[0]; e != null; e = e.next) { if(e.key == null) return e.val; } return null; } public void addListNode(int i, K key, V value) { ListNode<K, V> tmp = table[i]; table[i] = new ListNode<>(key, value); table[i].next = tmp; } } class People implements Comparable<People> { // 自定义People类,并覆盖了equals,hashCode,toString方法,实现了Comparable接口。 String name; int age; public People(String n, int a) { name = n; age = a; } @Override public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof People)) return false; return this.name.equals(((People)obj).name) && this.age == ((People)obj).age; } @Override public int hashCode() { return name.hashCode()*37 + age; } @Override public String toString() { return name + "," + age; } @Override public int compareTo(People o) { return this.age - o.age; } } public class TestClass { //测试类 public static void main(String[] args) { People[] people = new People[] { new People("xue", 25), new People("hong", 20), new People("jun", 21)}; Arrays.sort(people); // Collections.sort(Arrays.asList(people)); for (People peo : people) { System.out.println(peo); } HashMap<People, Integer> hm = new HashMap<People, Integer>(); for (int i = 0; i < people.length; i++) { hm.put(people[i], i); } for (int i = 0; i < people.length; i++) { System.out.println(hm.get(people[i])); } } }