大家都知道Map的内部存储实际上是一键值对,下面是书中介绍的map类图,我们可以看到map接口作为定级接口,
可以看到map作为定级接口,AbstracMap次之, map接口和AbstracMap定义了一些基本的方法,我们将这几两个基本的类定义完成之后,我们来实现下UnsortedTableMap,UnsortedTableMap 实现起来比较简单,因为我们使用arrayList来存储entry,而且还是无序的,当我们坐get,put,remove其实我们都需要一个操作,就是找到entry的位置,所以我们定义了一个方法叫做,findIndex ,剩下的就比较简单了,通过findIndex 找到entry在集合中的位置,然后添加,删除,查找
首先定义map接口
** * <p> * * @author <714037465@qq.com> * @since 2018/9/1116:54 **/ public interface Map<K, V> { int size(); boolean isEmpty(); V get(K k); V put(K k, V v); Iterable<K> keySet(); Iterable<V> values(); Iterable<Entry<K, V>> entrySet(); }
其次就是抽象类
package com.wangyadong.hobby.schedule.jobtask.map; import com.wangyadong.hobby.schedule.jobtask.tree.pq.Entry; import java.util.Iterator; public abstract class AbstractMap<K, V> implements Map<K, V> { public boolean isEmpty() { return size() == 0; } //---------------- nested MapEntry class ---------------- protected static class MapEntry<K, V> implements Entry<K, V> { private K k; // key private V v; // value public MapEntry(K key, V value) { k = key; v = value; } // public methods of the Entry interface public K getKey() { return k; } public V getValue() { return v; } // utilities not exposed as part of the Entry interface protected void setKey(K key) { k = key; } protected V setValue(V value) { V old = v; v = value; return old; } } //----------- end of nested MapEntry class ----------- // Support for public keySet method... private class KeyIterator implements Iterator<K> { private Iterator<Entry<K, V>> entries = entrySet().iterator(); // reuse entrySet public boolean hasNext() { return entries.hasNext(); } public K next() { return entries.next().getKey(); } // return key! public void remove() { throw new UnsupportedOperationException(); } } private class KeyIterable implements Iterable<K> { public Iterator<K> iterator() { return new KeyIterator(); } } public Iterable<K> keySet() { return new KeyIterable(); } // Support for public values method... private class ValueIterator implements Iterator<V> { private Iterator<Entry<K, V>> entries = entrySet().iterator(); // reuse entrySet public boolean hasNext() { return entries.hasNext(); } public V next() { return entries.next().getValue(); } // return value! public void remove() { throw new UnsupportedOperationException(); } } private class ValueIterable implements Iterable<V> { public Iterator<V> iterator() { return new ValueIterator(); } } public Iterable<V> values() { return new ValueIterable(); } }
最终我们的UnsortedTableMap
package com.wangyadong.hobby.schedule.jobtask.map; import com.wangyadong.hobby.schedule.jobtask.tree.pq.Entry; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; public class UnsortedTableMap<K, V> extends AbstractMap<K, V> { /** * Underlying storage for the map of entries. **/ private ArrayList<MapEntry<K, V>> table = new ArrayList<>(); /** * ∗ Constructs an initially empty map. ∗ **/ public UnsortedTableMap() { } /** * ∗Returns the index of an entry with equal key, or −1 if none found. **/ private int findIndex(K key) { int n = table.size(); for (int j = 0; j < n; j++) if (table.get(j).getKey().equals(key)) return j; return -1; // special value denotes that key was not found } /** * Returns the number of entries in the map. **/ public int size() { return table.size(); } /** * ∗ Returns the value associated with the specified key (or else null). **/ public V get(K key) { int j = findIndex(key); if (j == -1) return null; // not found return table.get(j).getValue(); } /** * ∗Associates given value with given key, replacing a previous value (if any). **/ public V put(K key, V value) { int j = findIndex(key); if (j == -1) { table.add(new MapEntry<>(key, value)); // add new entry return null; } else // key already exists return table.get(j).setValue(value); // replaced value is returned } /** * Removes the entry with the specified key (if any) and returns its value. / **/ public V remove(K key) { int j = findIndex(key); int n = size(); if (j == -1) return null; // not found V answer = table.get(j).getValue(); if (j != n - 1) table.set(j, table.get(n - 1)); // relocate last entry to ’hole’ created by removal table.remove(n - 1); // remove last entry of table return answer; } // Support for public entrySet method... private class EntryIterator implements Iterator<Entry<K, V>> { private int j = 0; public boolean hasNext() { return j < table.size(); } public Entry<K, V> next() { if (j == table.size()) throw new NoSuchElementException(); return table.get(j++); } public void remove() { throw new UnsupportedOperationException(); } } private class EntryIterable implements Iterable<Entry<K, V>> { public Iterator<Entry<K, V>> iterator() { return new EntryIterator(); } } //** Returns an iterable collection of all key-value entries of the map. **/ public Iterable<Entry<K, V>> entrySet() { return new EntryIterable(); } public static void main(String[] args) { UnsortedTableMap map = new UnsortedTableMap(); map.put("a", "1"); map.put("b", "2"); map.put("c", "3"); map.put("d", "4"); map.remove("a"); } }