1. 程式人生 > >實現Map接口(hash原理)

實現Map接口(hash原理)

bubuko lin 關聯 mov += quest urn port keyset

閑來無事,就實現一個簡單的map來練練手吧!

HashMap的底層實現主要是基於數組和鏈表來實現的,HashMap中通過key的hashCode來計算hash值的,由這個hash值計算在數組中的位置,將新插入的元素放到數組的這個位置,如果新插入的元素的hash值跟這個位置上已有元素的hash值相同,就會出現hash沖突,這時候,就在該位置通過鏈表來插入新的元素。

技術分享圖片

如圖,紫色部分是hash數組,綠色部分是鏈表,是為了解決沖突而產生的。

在實現Map接口時還需要實現Entry接口,以便能取出Map中元素。

package chapter3.question5;

import java.util.Map;

public class SimpleEntry implements Map.Entry, Comparable { private Object key; private Object value; public SimpleEntry(Object key, Object value) { this.key = key; this.value = value; } @Override public int compareTo(Object o) { SimpleEntry simpleEntry
= (SimpleEntry) o; return ((Comparable) key).compareTo(simpleEntry.key); } @Override public Object getKey() { return key; } @Override public Object getValue() { return value; } @Override public Object setValue(Object value) { Object result
= this.value; this.value = value; return result; } @Override public String toString() { return key + "=" + value; } }

接下來就是Map的簡單是實現啦。

package chapter3.question5;

import java.util.*;

public class SimpleMap implements Map {
    private final static int SLOT = 999;
    private LinkedList[] bucket = new LinkedList[SLOT];
    private int size = 0;

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean containsKey(Object key) {
        int index = key.hashCode() % SLOT;
        if (index < 0) index = -index;
        if (bucket[index] == null) return false;
        LinkedList linkedList = bucket[index];
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            SimpleEntry entry = (SimpleEntry) iterator.next();
            if (entry.getKey().equals(key)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean containsValue(Object value) {
        for (int i = 0; i < SLOT; i++) {
            if (bucket[i] != null) {
                LinkedList linkedList = bucket[i];
                Iterator iterator = linkedList.iterator();
                while (iterator.hasNext()) {
                    SimpleEntry entry = (SimpleEntry) iterator.next();
                    if (entry.getValue().equals(value)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public Object get(Object key) {
        int index = key.hashCode() % SLOT;
        if (index < 0) index = -index;
        if (bucket[index] == null) return null;
        LinkedList linkedList = bucket[index];
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            SimpleEntry entry = (SimpleEntry) iterator.next();
            if (entry.getKey().equals(key)) {
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * @param key
     * @param value
     * @return 此前與key關聯的值
     */
    @Override
    public Object put(Object key, Object value) {
        int index = key.hashCode() % SLOT;
        if (index < 0) index = -index;
        SimpleEntry entry = new SimpleEntry(key, value);
        Object prev = null;
        if (bucket[index] == null) bucket[index] = new LinkedList();
        LinkedList list = bucket[index];
        boolean found = false;
        ListIterator iterator = list.listIterator();
        while (iterator.hasNext()) {
            SimpleEntry simpleEntry = (SimpleEntry) iterator.next();
            if (simpleEntry.equals(entry)) {//一對一
                found = true;
                prev = simpleEntry.getValue();
                iterator.set(entry);
                break;
            }
        }
        if (!found) {
            size++;
            bucket[index].add(entry);
        }
        return prev;
    }

    @Override
    public Object remove(Object key) {
        SimpleEntry entry = null;
        int index = key.hashCode() % SLOT;
        if (index < 0) index = -index;
        if (bucket[index] == null) return null;
        LinkedList linkedList = bucket[index];
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            SimpleEntry simpleEntry = (SimpleEntry) iterator.next();
            if (simpleEntry.getKey().equals(key)) {
                entry = simpleEntry;
                iterator.remove();
                size--;
                break;
            }
        }
        return entry;
    }

    @Override
    public void putAll(Map m) {
        Set set = m.entrySet();
        for (Object object : set) {
            Map.Entry oo = (Map.Entry) object;
            put(oo.getKey(), oo.getValue());
        }
    }

    @Override
    public void clear() {
        for (Object key : keySet()) {
            remove(key);
        }
        size = 0;
    }

    @Override
    public Set keySet() {
        Set set = new HashSet();
        for (int i = 0; i < SLOT; i++) {
            if (bucket[i] != null) {
                Iterator iterator = bucket[i].iterator();
                while (iterator.hasNext()) {
                    set.add(((SimpleEntry) iterator.next()).getKey());
                }
            }
        }
        return set;
    }

    @Override
    public Collection values() {
        List list = new ArrayList();
        for (int i = 0; i < SLOT; i++) {
            if (bucket[i] != null) {
                Iterator iterator = bucket[i].iterator();
                while (iterator.hasNext()) {
                    list.add(((SimpleEntry) iterator.next()).getValue());
                }
            }
        }
        return list;
    }

    @Override
    public Set<Entry> entrySet() {
        Set set = new HashSet();
        for (int i = 0; i < SLOT; i++) {
            if (bucket[i] != null) {
                Iterator iterator = bucket[i].iterator();
                while (iterator.hasNext()) {
                    set.add(((SimpleEntry) iterator.next()));
                }
            }
        }
        return set;
    }

    @Override
    public int hashCode() {
        int j = 0;
        for (int i = 0; i < SLOT; i++) {
            if (bucket[i] != null) {
                Iterator iterator = bucket[i].iterator();
                j += ((SimpleEntry) iterator.next()).getKey().hashCode();
            }
        }
        return j;
    }

    /**
     * 為了測試顯示map內容
     *
     * @return
     */
    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < SLOT; i++) {
            if (bucket[i] != null) {
                Iterator iterator = bucket[i].iterator();
                while (iterator.hasNext()) {
                    SimpleEntry entry = (SimpleEntry) iterator.next();
                    stringBuilder.append(entry.getKey() + "," + entry.getValue() + "\n");
                }
            }
        }
        return stringBuilder.toString();
    }
}

實現Map接口(hash原理)