`

Map及其子类源码简单分析以及性能比较

    博客分类:
  • java
 
阅读更多

1.HashMap

构造:key-value键值对,key采用hash函数来排列,加快查询速度

 

  /**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

HashMap中key支持为null

 

<span style="white-space:pre">	</span>@Test
	public void Test(){
		Map<String, String> map = new HashMap<String, String>();
		map.put(null, "tom1");
		map.put("key2", "tom2");
		map.entrySet();
		for(Entry<String, String> set:map.entrySet()){
			System.out.println(set.getKey()+"<>"+map.get(set.getKey()));
		}
		
	}

 

2.TreeMap

 

构造:键值对,增加一个comparator参数对key进行默认排序

 

  /**
     * Constructs a new, empty tree map, ordered according to the given
     * comparator.  All keys inserted into the map must be <em>mutually
     * comparable</em> by the given comparator: {@code comparator.compare(k1,
     * k2)} must not throw a {@code ClassCastException} for any keys
     * {@code k1} and {@code k2} in the map.  If the user attempts to put
     * a key into the map that violates this constraint, the {@code put(Object
     * key, Object value)} call will throw a
     * {@code ClassCastException}.
     *
     * @param comparator the comparator that will be used to order this map.
     *        If {@code null}, the {@linkplain Comparable natural
     *        ordering} of the keys will be used.
     */
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }

put()时是即对key做排序,效率不会太高,所以只适用特定的环境

 

 public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }

3.ConcurrentHashMap

并发的HashMap,默认并发级别为16线程
public ConcurrentHashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
    }
put写操作是线程安全的,且是并发写到segments中
/**
     * Maps the specified key to the specified value in this table.
     * Neither the key nor the value can be null.
     *
     * <p> The value can be retrieved by calling the <tt>get</tt> method
     * with a key that is equal to the original key.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
     * @throws NullPointerException if the specified key or value is null
     */
    @SuppressWarnings("unchecked")
    public V put(K key, V value) {
        Segment<K,V> s;
        if (value == null)
            throw new NullPointerException();
        int hash = hash(key);
        int j = (hash >>> segmentShift) & segmentMask;
        if ((s = (Segment<K,V>)UNSAFE.getObject          // nonvolatile; recheck
             (segments, (j << SSHIFT) + SBASE)) == null) //  in ensureSegment
            s = ensureSegment(j); //确定哪个segment
        return s.put(key, hash, value, false);
    }

size()锁定所有segments,然后统计所有segments中的kv个数
 /**
     * Returns the number of key-value mappings in this map.  If the
     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
     * <tt>Integer.MAX_VALUE</tt>.
     *
     * @return the number of key-value mappings in this map
     */
    public int size() {
        // Try a few times to get accurate count. On failure due to
        // continuous async changes in table, resort to locking.
        final Segment<K,V>[] segments = this.segments;
        int size;
        boolean overflow; // true if size overflows 32 bits
        long sum;         // sum of modCounts
        long last = 0L;   // previous sum
        int retries = -1; // first iteration isn't retry
        try {
            for (;;) {
                if (retries++ == RETRIES_BEFORE_LOCK) {
                    for (int j = 0; j < segments.length; ++j)
                        ensureSegment(j).lock(); // force creation 循环锁定所有segments
                }
                sum = 0L;
                size = 0;
                overflow = false;
                for (int j = 0; j < segments.length; ++j) {
                    Segment<K,V> seg = segmentAt(segments, j);
                    if (seg != null) {
                        sum += seg.modCount;
                        int c = seg.count;
                        if (c < 0 || (size += c) < 0)
                            overflow = true;
                    }
                }
                if (sum == last)
                    break;
                last = sum;
            }
        } finally {
            if (retries > RETRIES_BEFORE_LOCK) {
                for (int j = 0; j < segments.length; ++j)
                    segmentAt(segments, j).unlock();
            }
        }
        return overflow ? Integer.MAX_VALUE : size;
    }
 

4.后记

记录与分享,你我共成长 -fromcaicongyang

 

 

 

 



分享到:
评论

相关推荐

    google map for android源码

    1. **MapView**:这是显示地图的主要组件,它是SurfaceView的子类,负责渲染地图、处理触摸事件以及与其他Google Maps组件交互。源码会展示如何加载不同级别的地图瓦片,以及如何处理地图的平移、缩放和旋转。 2. *...

    Map-main-源码.rar

    本篇文章将主要围绕这些Map的主要实现类进行源码分析,探讨其内部工作原理。 一、HashMap HashMap是最常用的Map实现类,它的核心原理是基于哈希表。HashMap使用一个Entry数组存储键值对,其中Entry是一个内部类,...

    java源码文档src

    例如,`java.io`包下的`File`类用于文件操作,`InputStream`和`OutputStream`接口及其子类处理输入输出流,`java.nio`包引入了非阻塞I/O模型,提高了性能。通过深入理解这些类和接口,开发者能更好地进行文件操作、...

    hibernate源码分析过程

    Hibernate 源码分析过程 Hibernate 是一个基于 Java 的 ORM(Object-Relation Mapping)框架,允许开发者使用面向对象的方式与关系数据库交互。在本文中,我们将对 Hibernate 的源码进行深入分析,并探讨其核心特性...

    Java常用类源码

    通过源码分析,我们可以理解它们各自的性能特点和适用场景。 3. `HashMap` 和 `TreeMap` 类:这两个类实现了`Map`接口,用于存储键值对。`HashMap`提供快速的插入、删除和查找,依赖于哈希表;`TreeMap`则按照键的...

    android 美食天下源码 googlemap

    【Android 美食天下源码 GoogleMap 深度解析】 在移动应用开发领域,Android平台因其开源、灵活的特点,成为了许多开发者首选的开发环境。"美食天下源码"是一个典型的Android应用示例,专注于美食分享和推荐,其中...

    28个java常用的类库源码

    通过阅读和分析这些源码,你不仅可以提升编程技能,还能了解到设计模式、性能优化、内存管理等多个方面的知识。每个类库都是一本教科书,揭示了Java平台的内在运作机制。这28个工具类源码的学习将是一次宝贵的实践...

    Java1.6源码

    9. **异常处理**:Java的异常处理是通过`Exception`类及其子类实现的,源码中可以学习到异常的抛出、捕获和处理机制。 10. **安全机制**:`java.security`包提供了安全管理的框架,包括密钥管理、证书、权限控制等...

    浅谈react-router@4.0 使用方法和源码分析

    React Router 是一个基于React之上的路由库,它用于构建单页应用程序(SPA),支持客户端路由以及编程式导航。在本篇文章中,将详细讨论React Router v4版本的使用方法和源码分析,该版本相较于之前的版本有了较大的...

    java入门学习源码

    Java是一种广泛使用的面向对象的编程语言,以其跨平台、高性能和丰富的类库而闻名。"java入门学习源码"这个主题对于初学者来说是极为重要的,因为它提供了实践和理解Java编程概念的实操机会。下面将详细介绍Java学习...

    JAVA面试及相关实现源码

    源码示例可能会展示如何在不同的子类中重写父类的方法,以及如何在运行时动态绑定调用相应的方法。 2. **异常处理(Exception Handling)** Java的异常处理机制是通过try-catch-finally语句块来实现的。面试中常见...

    【经典Android游戏源码20】坦克大战游戏源码

    【经典Android游戏源码20】坦克大战游戏源码是一个非常适合初学者和进阶开发者学习的项目,它展示了如何在Android平台上实现一个完整的2D游戏。这个游戏基于经典的坦克战斗概念,玩家可以控制自己的坦克,与敌方坦克...

    SpringMVC源码分析系列

    本文将通过源码分析,深入探索SpringMVC视图层的核心原理及关键组件。 首先,我们从视图层的基础接口View开始。View接口定义了两个基本方法:getContentType和render。getContentType用于获取视图生成内容的类型,...

    疯狂java讲义 程序源码

    - 继承:源码中会有子类继承父类的例子,展示如何扩展已有功能。 - 多态:通过接口和抽象类实现多态性,源码将展示如何编写和使用多态方法。 - 接口与抽象类:了解何时使用接口,何时使用抽象类,以及它们在实际...

    Java源码分析:集合-容器.pdf

    LinkedHashSet是HashSet的一个子类,它维护了一个链表记录插入元素的顺序,因此在遍历时能保持元素的添加顺序。 在双列集合中,Map接口定义了存储键值对的能力。HashMap是非线程安全的,它的数据结构基于数组和链表...

    shuffle的关键阶段sort(Map端和Reduce端)源码分析

    shuffle 的关键阶段 sort(Map 端和 Reduce 端)源码分析 在 Hadoop 的 MapReduce 框架中,排序是 shuffle 过程中的一个关键阶段。排序的目的是将数据按照特定的顺序排列,以便于后续的处理。今天,我们将深入分析 ...

    百度地图API源码

    【百度地图API源码】是Android开发中一个重要的学习...总之,这份【百度地图API源码】是一个宝贵的实践教程,通过深入学习和分析,开发者可以掌握Android平台上利用百度地图进行开发的全面技术,提升自己的专业技能。

    jdk源码学习

    4. **异常处理(Exception Handling)**:Java的异常处理机制是通过`try-catch-finally`语句来实现的,异常类位于`java.lang.Throwable`及其子类中。源码分析可以帮助理解如何正确地处理错误和异常。 5. **多线程...

    Java2核心技术卷一 配套源码

    此外,Java集合框架是处理对象集合的重要工具,包括List、Set、Map等接口及其实现类。源码会展示如何创建和操作这些集合,以及如何使用泛型来增强类型安全。 线程是Java的另一大特色。Java提供了内置的多线程支持,...

    Java2核心技术卷二 配套源码

    源码会展示如何使用InputStream、OutputStream、Reader、Writer及其子类进行数据的读写。 5. **异常处理**:Java的异常处理机制通过try-catch-finally语句块来捕获和处理运行时错误。源码会演示如何正确地抛出和...

Global site tag (gtag.js) - Google Analytics