zoukankan      html  css  js  c++  java
  • java

    ---恢复内容开始---

    AbstractMap类是一个抽象类,与map接口类不同的是,abstractmap是map的一个“skeletal implementation”(骨架实现),用处是减少实现map接口的工作量。

    首先,我们需要看一下这个类的内部实体类SimpleEntry

    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;
            }
    
        }

    代码如上,很明显的看出就是一个实体类数据集合,包含一个key2value的对象,同时提供了object类的接口实现,很明显的看出来,entry类的equals比较方法,是进行key值对比和value对比,hashCode()方法会进行key的hash和value的hash进行异或操作,而若某值为空,也会产生hash为0的现状。

    之后我们看看abstractmap对这个数据集怎么进行处理的。

    public abstract Set<Entry<K,V>> entrySet();

    此为该操作对象集,实现的map接口,同时也可以继承上面的simpleentry进行改写。显而易见作为一个set集,代表其中没有重复的内容,保证不重复的关键就是key值不重复。

    public int size() {
            return entrySet().size();
        }

    size返回的也是数据集的大小。

        public boolean isEmpty() {
            return size() == 0;
        }
        public boolean containsValue(Object value) {
            Iterator<Entry<K,V>> i = entrySet().iterator();
            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;
        }

    containsValue主要是迭代器遍历,还针对value是否为空进行分叉,主要也是因为equals会被重写。

        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;
        }

    same old things

        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;
        }

    get也是通过迭代器进行的查找,比较蛋疼,居然是遍历,然后根据key值对应的value进行操作,感觉时间复杂度还是比较大的。

        public V put(K key, V value) {
            throw new UnsupportedOperationException();
        }

    这个就是必须要复写了,否则就爆异常。

        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();
                    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();
                i.remove();
            }
            return oldValue;
        }
  • 相关阅读:
    springMVC web项目转springboot web项目的杂谈
    testNG的DataProvider返回Iterator<Object[]>的妙用
    java+testng利用json格式的txt做数据源的数据驱动示例
    搭建rest-assured接口自动化框架遇到的坑
    Linux SAR命令详解
    springboot集成jsp需添加的包依赖
    springboot集成jsp,页面跳转问题记录
    Spring Boot 使用JSP时,启动热部署配置
    性能测试大牛推荐的必读书单
    ARP详解(转)
  • 原文地址:https://www.cnblogs.com/Sample1994/p/7443000.html
Copyright © 2011-2022 走看看