JDK源码阅读计划(Day6) AbstractMap & AbstractSet

JDK11

AbstractMap

public abstract class AbstractMap<K,V> implements Map<K,V> {

Map的抽象类实现,那有哪些Map继承了这个抽象类呢?

  • EnumMap
  • HashMap
  • IdentityHashMap
  • LinkedHashMap
  • WeakHashMap
  • TreeMap

未来一周的计划就是把这些Map的底层实现彻底搞懂

 transient Set<K> keySet;        // key的集合
 transient Collection<V> values; // value的集合
// 常用的entrySet实际上是一个Set,基本数据类型是Entry<K,V> 
public abstract Set<Entry<K, V>> entrySet();

那这个Entry又指的是什么呢?

这个键值对实体的实现定义在Map.java

interface Entry<K, V> {
  • hashCode

Map的hascode等于所有entry的hashCode之和

 public int hashCode() {
        int h = 0;
        for(Entry<K, V> entry : entrySet()) {
            h += entry.hashCode();
        }
        return h;
    }
  • equals

1.如果所比较对象等于自身引用返回true
2.如果所比较对象不是Map类型返回false
3.把所比较对象类型转换为Map
4.互相比较两个map的entry,如果value为null,判断条件是map存在对应的key并且比较对象的key对应value也为null
如果value不为null,判断条件是用equals判断是否相同。

public boolean equals(Object o) {
        if(o == this) {
            return true;
        }
        
        if(!(o instanceof Map)) {
            return false;
        }
        
        Map<?, ?> m = (Map<?, ?>) o;
        if(m.size() != size()) {
            return false;
        }
        
        try {
            for(Entry<K, V> e : entrySet()) {
                K key = e.getKey();
                V value = e.getValue();
                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;
    }
  • toString

没啥好说的,就用StringBuilder

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(' ');
        }
    }
  • clone
    浅拷贝,只复制了map应用本身,其key和value都是没有复制的,都是指向原来的key和value
 protected Object clone() throws CloneNotSupportedException {
      AbstractMap<?, ?> result = (AbstractMap<?, ?>) super.clone();
      result.keySet = null;
      result.values = null;
      return result;
  }

其他的put,get,remove方法都很常规我就不说了

另外要提一下定义了两个简单的键值对实现了Entry接口

  • SimpleEntry

  • SimpleImmutableEntry

两个区别是后者的value用了final修饰,setValue方法并没有实现,抛出Exception

Entry的hashcode方法:

public int hashCode() {
        return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
}

key和value取异或

AbstractSet

public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {

和AbstractMap不同的是,这个抽象类还继承了AbstractCollection这个抽象父类,

在这里插入图片描述

public boolean equals(Object o) {
        if(o == this) {
            return true;
        }
        if(!(o instanceof Set)) {
            return false;
        }
        Collection<?> c = (Collection<?>) o;
        if(c.size() != size()) {
            return false;
        }
        try {
           // 只要两个set包含的元素都相同就可以说明equals
            return containsAll(c);
        } catch(ClassCastException | NullPointerException unused) {
            return false;
        }
    }
  • hashcode
public int hashCode() {
        int h = 0;
        
        for(E obj : this) {
            if(obj != null) {
                h += obj.hashCode();
         
            }
        }
        return h;
    }

Set中所有元素hashcode累加和

  • removeAll

没啥好说的。。。

 public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        
        boolean modified = false;
        
        if(size()>c.size()) {
            for(Object e : c) {
                modified |= remove(e);
            }
        } else {
            for(Iterator<?> i = iterator(); i.hasNext(); ) {
                if(c.contains(i.next())) {
                    i.remove();
                    modified = true;
                }
            }
        }
        
        return modified;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值