Thinking in Java之Map接口源码学习

       

         欢迎讨论、交流,转载请注明出处,3Q!

        前言

               在前面的文章中 笔者就Collection接口、及其下的子接口和实现类做了相关的总结。这篇文章

            笔者将会对Map接口和其的一个实现类HashMap的源码进行分析,做一些总结。

        Map接口

                对于Map接口和其实现类的UML图例读者可以参考笔者的以前写的文章“Java集合框架浅析”地址

           如下:http://blog.csdn.net/kiritor/article/details/8868943

                Map接口提供了一个更为通用的元素存储方案,即以"键值对“的形式存储,其中的键(Key)是唯一

           的,每个key都映射到一个值。Map接口没有规定其集合中元素的顺序情况,其映射顺序定义为迭代

           器在映射的collection上返回其元素的顺序。Map集合的元素顺序情况时有实现它的具体类来体现的。

                例如TreeMap确保顺序,而HashMap这不确保其顺序。

       Map接口设计

               接下来我们从源码中来看Map的相关设计,Map是接口只是提供一些方法声明并未实现。不过这

          没有关系,我们需要的是对于Map接口的理解,方便于之后我们对其实现子类的学习。笔者简单的

          将Map的源码实现给出:

package com.kiritor; /** Map 接口源码*/ import java.util.Collection; import java.util.HashMap; import java.util.Hashtable; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; public interface Map<K,V> {     /**Map的大小*/     int size();     //Map是否为空     boolean isEmpty();     //Map是否包含某个键    boolean containsKey(Object key);     //Map是否包含某个值     boolean containsValue(Object value);     //放入元素     V put(K key, V value);     void putAll(Map<? extends K, ? extends V> m);      //返回键视图     Set<K> keySet();     //返回值视图     Collection<V> values();     //返回键值对视图     Set<Map.Entry<K, V>> entrySet();     interface Entry<K,V> {         K getKey();         V getValue();         V setValue(V value);         boolean equals(Object o);         int hashCode();     }     boolean equals(Object o);     int hashCode();  } 
           通过观察可以知道Map接口里面还有一个内部接口Entry<K,V>,其意思有"记录"的意思。

       它存放的就是"键值对"的信息。至于这个键值对是如何存储的我们先不讨论。接下来对Map

       接口的一些方法坐下分析。

          Map构建

              Map接口中定义了几个用于插入和删除元素的方法

           

          Map访问

               观察Map源代码可以发现的是Map接口并未定义迭代器方法,那么我们如何对Map进行遍历

            访问呢?首先需要明白的是无论如何,要进行迭代就必然需要获取Map”视图“,通过对源码方法

             的观察这里存在着三种视图。

                      ● 所有键值对:entrySet()方法。

                      ● 所有键:keySet()方法。

                      ● 所有值:values()方法。

                 根据方法返回值可以知道前两个视图返回的是Set对象,第三个视图返回的是一个Collection

             对象。由这三个视图我们就可以实现对Map的遍历访问了。  

Iterator keyValuePairs = aMap.entrySet().iterator(); Iterator keys = aMap.keySet().iterator(); Iterator values = aMap.values().iterator();

             Map对象比较

              

             核心Map

                    Java自带了各种各样Map,大体上可以分为三类:

                       1、通用 Map,用于在应用程序中管理映射,通常在 java.util 程序包中实现
                             HashMap
                             Hashtable
                             Properties
                             LinkedHashMap
                             IdentityHashMap
                             TreeMap
                             WeakHashMap
                             ConcurrentHashMap
                      2、专用 Map,您通常不必亲自创建此类 Map,而是通过某些其他类对其进行访问
                             java.util.jar.Attributes
                             javax.print.attribute.standard.PrinterStateReasons
                             java.security.Provider
                             java.awt.RenderingHints
                             javax.swing.UIDefaults
                      3、一个用于帮助实现您自己的 Map 类的抽象类
                             AbstractMap

           内部哈希:哈希映射技术

                  在学习HashMap之前我们必须先要明白什么叫内部哈希以及它的实现原理。

                  几乎所有的通用的Map都使用的是哈希映射。哈希映射就是一种将元素映射到数据的简单的

              机制。

                   哈希映射结构由一个存储元素的内部数组组成由于内部采用数组存储,因此必然存在一个用

              与确定任意键访问数组的索引机制。这个机制就叫做哈希函数。在Java基于哈希的Map中,哈希

              函数将对象转换一个适合内部数组的整数。一般情况下,每个对象都包含一个返回整数值的

              hashCode()方法,要将该值映射到数组,只需将其转换为一个正值,然后改值除以数组的大

              小去余数计科。下面简单的产生一个哈希函数。

int hashvalue = Maths.abs(key.hashCode()) % table.length;

                 上面也说了hashCode()方法产生的是一个整数,到底hashCode()方法又是一个什么玩意儿呢?

               请参考这篇文章:

                http://blog.csdn.net/kiritor/article/details/8885022

你可能感兴趣的:(遍历,HashCode,Map源码,哈希值)