java集合系列14 AbstractMap

xiaoxiao2021-02-27  179

前言

离HashMap又进了一步

AbstractMap提供了对Map接口的骨架实现,以减少实现Map接口所做出的努力。

还是架构图,这Map接口有大体的了解,方便翻看

AbstractMap文档

要实现一个不更改的map,编程人员只需要继承此类并提供对entrySet方法的实现(返回映射的映射关系的set视图)。通常,返回的set将依次在AbstractSet上实现。此Set就该不支持add或remove方法,并且共迭代器应不支持remove方法

要实现一个可更改的map,编程人员必须额外的重写此类的put方法(否则将抛出一个UnsupportedOperationException),并且entrySet().iterator()应该额外实现其remove方法

编程人员应提供一个无参和一个带有map类型参数的构造器,按照Map接口规范中的建议

源码

public abstract class AbstractMap<K, V> implements Map<K, V>{ /** * 唯一的构造器(供子类的构造器调用,通常是隐式调用) */ public AbstractMap() { } /** * 此实现返回entrySet().size() */ public int size(){ return entrySet().size(); } /** * 此实现返回 size() == 0 */ public boolean isEmpty(){ return size() == 0; } /** * 此实现迭代整个enterSet()寻找具有指定value的entry. * 如果找到了这样的entry,返回true. * 如果直到迭代终止还没有找到这样的entry 返回false * 注意:此实现需要的时间与map的大小成线性关系 */ public boolean containsValue(Object value){ Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if(value == null){ while (i.hasNext()){ Map.Entry<K, V> e = i.next(); if(e.getValue() == null){ return true; } } }else{ while(i.hasNext()){ Map.Entry<K, V> e = i.next(); if (value.equals(e.getValue())) { return true; } } } return false; } /** * 此实现迭代entrySet()寻找一个具有指定key的entry. * 如果找到了这样的entry,返回true. * 如果直到迭代终止,还没有找到这样的entry,返回false * 注意:此实现需要花费的时间与map的大小成线性关系; * 许多实现将会重写此方法 */ public boolean containsKey(Object key){ Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if (key == null) { while (i.hasNext()) { Map.Entry<K, V> e = i.next(); if (e.getValue() == null) { return true; } } }else { while (i.hasNext()) { Map.Entry<K, V> e = i.next(); if (key.equals(e.getKey())) { return true; } } } return false; } /** * 此实现迭代entrySet()寻找具有指定key的entry. * 如果找到了这样的entry,返回entry的value值. * 如果直到迭代终止还没有找到这样的entry,返回null * 注意:此实现需要花费的时间与map的大小成正比 * 许多实现将会重写此方法 */ public V get(Object key) { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if(key == null){ while (i.hasNext()) { Map.Entry<K, V> e = i.next(); if(e.getKey() == null){ return e.getValue(); } } }else { while (i.hasNext()){ Map.Entry<K, V> e = i.next(); if (key.equals(e.getKey())) { return e.getValue(); } } } return null; } /** * 此实现永远抛出UnsupportedOperationExcetion */ public V put(K key, V value){ throw new UnsupportedOperationException(); } /** * 此实现迭代entrySet()寻找具有指定key的entry. * 如果找到这样的entry,其value值由其自身的getValue方法获取 * 此entry会由迭代器的remove操作移除,然后返回保存的值。 * 如果直到迭代终止还没有找到这样的entry,返回null. * * 注意:此实现需要花费的时间与map的大小成正比; * 许多实现将会重写此方法 * 注意:此实现会抛出UnsupportedOperation如果entrySet的迭代器不支持 * remove方法并且此map具有指定key的entry */ public V remove(Object key){ Iterator<Map.Entry<K, V>> i = entrySet().iterator(); Map.Entry<K, V> correctEntry = null; if(key == null){ while (correctEntry == null && i.hasNext()){ Map.Entry<K, V> e = i.next(); if(e.getKey() == null){ correctEntry = e; } } }else{ while (correctEntry == null && i.hasNext()){ Map.Entry<K, V> e = i.next(); if (key.equals(e.getKey())) { correctEntry = e; } } } V oldValue = null; if(correctEntry != null){ oldValue = correctEntry.getValue(); i.remove(); } return oldValue; } /** * 此实现迭代指定map的entrySet(),并调用此map的put方法 * 注意:此实现将抛出UnsupprotedOperationExcetion 如果此map不支持put * 方法并且指定的集合非空 */ public void putAll(Map<? extends K, ? extends V> m){ for(Map.Entry<? extends K, ? extends V> e : m.entrySet()){ put(e.getKey(), e.getValue()); } } /** * 此实现调用entrySet().clear()方法 * * 注意:此实现将抛出一个UnsupportedOperation如果entrySet不支持clear操作 */ public void clear(){ entrySet().clear(); } public abstract Set<Map.Entry<K, V>> entrySet(); //视图 /** * 当此视图第一次需要时被创建。 * 视图是无状态的,所以没有原因没次都创建一个视图 */ transient Set<K> keySet; transient Collection<V> values; /** * 此实现返回一个AbstractSet的子类 * 此子类的iterator方法返回一个对entrySet迭代的包装对象 * size方法代表此map的size * catains方法代表此map的containsKey方法 * * 当此方法第一次被调用时set视图被创建并返回供后续调用. * 此方法不是同步的,因此当并发调用时有很小的机率返回的不是 * 同一个set * */ public Set<K> keySet(){ Set<K> ks = keySet; if(ks == null){ ks = new AbstractSet<K>() { @Override public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Map.Entry<K, V>> i = entrySet().iterator(); @Override public boolean hasNext() { return i.hasNext(); } @Override public K next() { return i.next().getKey(); } public void remove(){ i.remove(); } }; } @Override 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; } /** * 此实现返回一个AbstractCollection的子类。 * 此子类的iterator方法返回一个entreySet的迭代方法的包装对象。 * * size代表此map的size方法 * contains代表此map的containsValue方法 * * 当此方法第一次调用时才会创建collection视图,返回并供后续调用。 * 此方法的表现不是同步的,因此当并发调用此方法时,会有很小的机率返回的collection并不是同一个 * @return */ public Collection<V> values(){ if (values == null) { values = new AbstractCollection<V>() { @Override public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Map.Entry<K, V>> i = entrySet().iterator(); @Override public boolean hasNext() { return i.hasNext(); } @Override public V next() { return i.next().getValue(); } public void remove() { i.remove(); } }; } @Override 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); } }; } return values; } public boolean equals(Object o){ if (o == this) { return true; } if (!(o instanceof Map)) { return false; } Map<?, ?> m = (Map<?, ?>) o; try { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); while (i.hasNext()) { Map.Entry<K, V> e = i.next(); V value = e.getValue(); K key = e.getKey(); if (value == null) { if (!(m.get(key) == null && m.containsKey(key))) { return false; } } else { 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<Map.Entry<K, V>> i = entrySet().iterator(); while (i.hasNext()){ h += i.next().hashCode(); } return h; } public String toString(){ Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if(!i.hasNext()) { return "{}"; } StringBuilder sb = new StringBuilder(); sb.append('{'); for(;;){ Map.Entry<K, V> e = i.next(); V value = e.getValue(); K key = e.getKey(); sb.append(key == this ? "(this Map)" : key); sb.append(value == this ? "(this Map)" : value); if(!i.hasNext()){ return sb.append('}').toString(); } sb.append(',').append(' '); } } private static boolean eq(Object o1, Object o){ return o1 == null ? o == null : o1.equals(o); } /** * 一个简单的可更改value的entry */ public static class SimpleEntry<K, V> implements Map.Entry<K, V>, Serializable{ private static final long serialVersionUID = -849971149061103585L; private final K key; private V value; public SimpleEntry(K key, V value) { this.key = key; this.value = value; } public SimpleEntry(Map.Entry<? extends K, ? extends V> entry){ this.key = entry.getKey(); this.value = entry.getValue(); } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override 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; } } /** * 一个简单的value不可更改的entry */ public static class SimpleImmutableEntry<K, V> implements Map.Entry<K, V>, Serializable{ private static final long serialVersionUID = 713839143949025153L; private final K key; private final V value; public SimpleImmutableEntry(K key, V value) { this.key = key; this.value = value; } public SimpleImmutableEntry(Map.Entry<? extends K, ? extends V> entry){ this.key = entry.getKey(); this.value = entry.getValue(); } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(V value) { throw new UnsupportedOperationException(); } 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; } } }

参考

JDK1.8 AbstractMap

转载请注明原文地址: https://www.6miu.com/read-13193.html

最新回复(0)