实现一个简单的散列表(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]));
        }
    }
}
原文地址:https://www.cnblogs.com/lasclocker/p/4857771.html