大家都知道Map的内部存储实际上是一键值对,下面是书中介绍的map类图,我们可以看到map接口作为定级接口,
可以看到map作为定级接口,AbstracMap次之, map接口和AbstracMap定义了一些基本的方法,我们将这几两个基本的类定义完成之后,我们来实现下UnsortedTableMap,UnsortedTableMap 实现起来比较简单,因为我们使用arrayList来存储entry,而且还是无序的,当我们坐get,put,remove其实我们都需要一个操作,就是找到entry的位置,所以我们定义了一个方法叫做,findIndex ,剩下的就比较简单了,通过findIndex 找到entry在集合中的位置,然后添加,删除,查找
首先定义map接口
** * <p> * * @author <[email protected]> * @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");
}
}