走进JDK(九)------AbstractMap 一、类定义、构造函数、成员变量 二、主要方法
map其实就是键值对,要想学习好map,得先从AbstractMap开始。
public abstract class AbstractMap<K,V> implements Map<K,V> protected AbstractMap() { }
这是个抽象类,很明显只是为子类们提供一些共用的方法模板。
成员变量:
transient Set<K> keySet;//说明abstractMap中的key是不允许重复的
transient Collection<V> values;//value当然可以重复
//map当中的实体,代表一个键值对 public abstract Set<Entry<K,V>> entrySet(); public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable { private static final long serialVersionUID = -8499721149061103585L; private final K key; private V value; public SimpleEntry(K key, V value) { this.key = key; this.value = value; } public SimpleEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public K getKey() { return key; } public V getValue() { return value; } public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry<?,?>)o; return eq(key, e.getKey()) && eq(value, e.getValue()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } }
二、主要方法
1、size()
public int size() { //返回entry的数量 return entrySet().size(); }
2、isEmpty()
public boolean isEmpty() { //判断entry数量是否为0 return size() == 0; }
3、containsValue()、containsKey()
public boolean containsValue(Object value) { //entrySet循环,因为是个set,所以可用iterator,set后面的博文介绍 Iterator<Entry<K,V>> i = entrySet().iterator(); //这个问题已经解释很多次了,判断非null主要就是为了防止使用equals()报错。而且很多不同子类就会重写object父类的equals方法,例如Stirng的equals(),所以为null的时候就比较内存地址,不为null就调用value具体equals(),例如string就是判断字符串是否相等 if (value==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getValue()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (value.equals(e.getValue())) return true; } } return false; } //此方法与上面方法没啥差别,只是一个比较value,一个比较key public boolean containsKey(Object key) { Iterator<Map.Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return true; } } return false; }
4、get()
//此方法也很简单,没啥说的。。。 public V get(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return e.getValue(); } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return e.getValue(); } } return null; }
5、put()、putAll()
public V put(K key, V value) { //由子类实现,父类不提供具体的操作逻辑 throw new UnsupportedOperationException(); } public void putAll(Map<? extends K, ? extends V> m) { //循环要加入的map的entry,然后将键值对加入到当前map中 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) put(e.getKey(), e.getValue()); }
6、remove()、clear()
public V remove(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); Entry<K,V> correctEntry = null; if (key==null) { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); //如果map中的key为null if (e.getKey()==null) //这地方是为了退出循环 correctEntry = e; } } else { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) correctEntry = e; } } V oldValue = null; if (correctEntry !=null) { oldValue = correctEntry.getValue(); //由于上面循环到了当前entry并赋值给了correctEntry,因此调用remove()删除的就是此entry i.remove(); } return oldValue; } //清除所有的entry public void clear() { entrySet().clear(); }
7、keySet()
//获取当前map中的所有key,并放到set中 public Set<K> keySet() { Set<K> ks = keySet; //如果之前有调用过keySet方法,则直接给出所有的key if (ks == null) { //内部使用了AbstractSet,并且还弄了个匿名内部类也就是AbstractSet啦。其实本质上就相当于编写一个子类继承AbstractCollection,并且实现了hasNext()、next()等方法。
然后将entrySet.iterator赋值给当前的set,等到后面使用的时候,再去取所有的key
ks = new AbstractSet<K>() { public Iterator<K> iterator() { return new Iterator<K>() { //拿到所有的entry private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public K next() { return i.next().getKey(); } public void remove() { i.remove(); } }; } public int size() { return AbstractMap.this.size(); } public boolean isEmpty() { return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap.this.clear(); } public boolean contains(Object k) { return AbstractMap.this.containsKey(k); } }; keySet = ks; } return ks; }
8、values()
//这个类跟keySet本质上是一回事,就是编写一个子类继承AbstractCollection,并且实现了hasNext()、next()等方法 public Collection<V> values() { Collection<V> vals = values; if (vals == null) { vals = new AbstractCollection<V>() { public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public V next() { return i.next().getValue(); } public void remove() { i.remove(); } }; } public int size() { return AbstractMap.this.size(); } public boolean isEmpty() { return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap.this.clear(); } public boolean contains(Object v) { return AbstractMap.this.containsValue(v); } }; values = vals; } return vals; }
9、equals()、hashCode()、toString()、clone()
public boolean equals(Object o) { if (o == this) return true; //不为map肯定不相等了 if (!(o instanceof Map)) return false; Map<?,?> m = (Map<?,?>) o; //长度不相等也没啥好比的 if (m.size() != size()) return false; try { Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); //当value为null时 if (value == null) { //比较对象的value为null并且包含相同的key,否则不相等 if (!(m.get(key)==null && m.containsKey(key))) return false; } else { //value不为null时,直接拿比较对象的key取m中取value值,如果value不为null,说明key存在,然后判断value即可 if (!value.equals(m.get(key))) return false; } } } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } return true; } public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; } public String toString() { Iterator<Entry<K,V>> i = entrySet().iterator(); if (! i.hasNext()) return "{}"; StringBuilder sb = new StringBuilder(); sb.append('{'); for (;;) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); sb.append(key == this ? "(this Map)" : key); sb.append('='); sb.append(value == this ? "(this Map)" : value); if (! i.hasNext()) return sb.append('}').toString(); sb.append(',').append(' '); } } protected Object clone() throws CloneNotSupportedException { AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone(); result.keySet = null; result.values = null; return result; }