文章出處

今天本人想要復習的是哈希表(散列表)的概念及具體實現,為此用java寫了一個簡單的實現,但僅僅只是實現了一些簡單的功能,不過通過這個簡單的實現的確可以幫助我們進一步理解JDK中的HashMap,當然,想要進一步了解就直接閱讀JDK中的HashMap的源碼啦。

實現代碼如下,有注釋,本人就不進一步闡述了:

/** * 該類是HashMap的一個簡單實現。 *  * 這里,我主要采用一個元素是鏈表的數組來模擬JDK中的HashMap實現。 當存入一個鍵值對(K,V)的時候,首先計算鍵(K)對應的HashCode。這個HashCode的值其實就是具體實現過程中用到的數組的索引。通過計算鍵的HashCode值便可以知道應該將鍵值對(K,V)存儲在第幾個數組元素中。如前所述,每一個數組元素其實又是一個鏈表。將鍵值對存入散列表其實是存入底層數組元素對應的鏈表結構中。之所以使用鏈表作為數組元素是為了避免HashCode相同但又不相等的鍵造成沖突時候相互覆蓋的問題。這樣就很好的解決了可能存在的碰撞沖突問題。 *  * @author lhever * * @param  * @param  */public class SimpleHashMap {    public static final int INITIAL_CAPACITY = 4;    private int N;    private int M;    private SequentialST[] table;    /**     * 構造     */    public SimpleHashMap() {        this(INITIAL_CAPACITY);    }    /**     * 構造,可以指定底層數組的大小     *      * @param M     */    public SimpleHashMap(int M) {        this.M = M;        table = (SequentialST[]) new SequentialST[M];        for (int i = 0; i < M; i++) {            table[i] = new SequentialST();        }    }    /**     * 重新調整底層數組的大小,從實現的角度看,所有已經 存入的鍵值對會被從新計算散列值并調整存儲的位置。     *      * @param newSize     */    private void resize(int newSize) {        SimpleHashMap temp = new SimpleHashMap(newSize);        for (int i = 0; i < M; i++) {            for (K key : table[i].keys()) {                temp.put(key, table[i].get(key));            }        }        this.M = temp.M;        this.N = temp.N;        this.table = temp.table;    }    private int hash(K key) {        return (key.hashCode() & 0x7fffffff) % M;    }    public int size() {        return N;    }    public boolean isEmpty() {        return size() == 0;    }    public boolean contains(K key) {        if (key == null) {            throw new NullPointerException("參數不能為null");        }        return get(key) != null;    }    public V get(K key) {        if (key == null) {            throw new NullPointerException("參數不能為null");        }        int i = hash(key);        return table[i].get(key);    }    public void put(K key, V val) {        if (key == null) {            throw new NullPointerException("key不能為null");        }        if (val == null) {            remove(key);            return;        }        // 當鏈表中的平均元素個數大于10的時候增加底層數組的大小(變為兩倍大)        if (N >= 10 * M) {            resize(2 * M);        }        int i = hash(key);        if (!table[i].contains(key)) {            N++;        }        table[i].put(key, val);    }    public void remove(K key) {        if (key == null) {            throw new NullPointerException("參數不能為null");        }        int i = hash(key);        if (table[i].contains(key)) {            N--;            table[i].delete(key);        }        // 如果列表中的平均元素個數小于等于2的時候,降低底層數組的大小(變為原來大小的1/2)        if (M > INITIAL_CAPACITY && N <= 2 * M) {            resize(M / 2);        }    }    // 返回一個迭代器,其中包含了所有的鍵    public Iterable keys() {        Queue queue = new LinkedList();        for (int i = 0; i < M; i++) {            for (K key : table[i].keys())                queue.offer(key);        }        return (Iterable) queue;    }    /**     * 測試     *      * @param args     */    public static void main(String... args) {        SimpleHashMap map = new SimpleHashMap();        map.put("country", "China");        map.put("level", "super");        map.put("nature", "public");        System.out.println(map.get("country"));        System.out.println("befor remove, the size is: " + map.size());        map.remove("country");        System.out.println("after remove, the size is: " + map.size());        for (String key : (Iterable) map.keys()) {            System.out.println(key + " : " + map.get(key));        }        map.remove("nature");        map.remove("level");        map.remove("level");        System.out.println("after remove, the size is: " + map.size());        for (String key : (Iterable) map.keys()) {            System.out.println(key + " : " + map.get(key));        }        map.put("size", "960");        System.out.println("after put, the size is: " + map.size());    }}////////////////////////////////////////////////////package lhever.Hash_Map;import java.util.LinkedList;import java.util.Queue;/** * 該類是一個順序查找的鏈表實現,查找元素時候會從第一個節點開始順序查找, * 該鏈表實現會被用到SimpleHashMap(JDK中HashMap的一個簡單實現)的實現中 *  * @author lhever * * @param  * @param  */public class SequentialST {    private int N;    private Node first;    /**     * 代表一個節點     *      * @author lhever     */    private class Node {        private K key;        private V value;        private Node next;        public Node(K key, V value, Node next) {            this.key = key;            this.value = value;            this.next = next;        }    }    public SequentialST() {    }    public int size() {        return N;    }    public boolean isEmpty() {        return size() == 0;    }    public boolean contains(K key) {        if (key == null)            throw new NullPointerException("參數不能為null");        return get(key) != null;    }    /**     * 查找從第一個節點開始順序進行     *      * @param key     * @return     */    public V get(K key) {        if (key == null)            throw new NullPointerException("參數不能為null");        for (Node node = first; node != null; node = node.next) {            if (key.equals(node.key))                return node.value;        }        return null;    }    /**     * 增加     *      * @param key     * @param value     */    public void put(K key, V value) {        if (key == null)            throw new NullPointerException("參數不能為null");        if (value == null) {            delete(key);            return;        }        for (Node node = first; node != null; node = node.next) {            if (key.equals(node.key)) {                node.value = value;                return;            }        }        first = new Node(key, value, first);        N++;    }    public void delete(K key) {        if (key == null)            throw new NullPointerException("參數不能為null");        first = delete(first, key);    }    private Node delete(Node node, K key) {        if (node == null)            return null;        if (key.equals(node.key)) {            N--;            return node.next;        }        node.next = delete(node.next, key);        return node;    }    public Iterable keys() {        Queue queue = new LinkedList();        for (Node node = first; node != null; node = node.next)            queue.offer(node.key);        return queue;    }},>,>,>,>,>,>,>,>

看文倉www.kanwencang.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20161027/11056.html

文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()