`
sunzhenya
  • 浏览: 697 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

map总结

 
阅读更多
Map集合 总结

博客分类: Map集合

      Java的集合类可分为Set、List、Map、Queue,其中Set、List、Queue都有共同的接口:Collection.

所以Collection和Map是Java集合框架的根接口。Java集合实际上并不是真的把对象放入其中,集合中保存的只是对象的引用。

这里首先讲Map,因为所有的Set底层都是由Map实现的,仔细观察API可以发现,Set集合继承体系中所有的接口、实现类的类名,对应的Map集合体系都有。

如:Set-->Map

  EnumSet-->EnumMap

  SortedSet-->SortedMap

  TreeSet-->TreeMap

  NavigableSet-->NavigableMap

  HashSet-->HashMap

  LinkedHashSet-->LinkedHashMap

所不同的是,Map集合体系中还包括IdetityHashMap、WeakHashMap、Hashtable、Properties实现类。

Map集合用于保存具有映射关系的数据,其本质就是一个Object类型的动态数组,数组元素是Map接口的内部类Entry。

内部类Entry封装了一个key-value对。

key和value存在单向的一对一关系,通过指定的key总能找到唯一的确定的value.

由于这个特征,就必须要求Key是不可重复的,符合Set的特征。事实上,Map中所有的key就组成了一个Set集合。

而Value是可以重复的。只能通过key查询value,可以把value看作key的附庸。



一、HashMap 和 Hashtable

Hashtable较为古老,是HashMap的线程安全形式。其中封装了许多古老的方法,与HashMap主要有两点区别:

1、HashMap线程不安全,Hashtable线程安全,所以HashMap性能更好。

  而实现线程安全用集合工具类Collections的静态方法synchronizedMap()包装一下,更简单、实用。

2、Hashtable不允许使用null作为key和value,会引发NullPointerException异常,而HashMap允许。

HashMap的底层是数组实现的,其数组元素为一个Entry链表(栈)。

存储过程:根据元素的hashCode()返回值计算元素在数组中的存储索引。根据元素equals方法来计算元素在Entry链表中的存储位置。

  若有2个元素hashCode()返回值相同而equals为false,那么发生哈希冲突。新增加的Entry总放在Entry链表栈顶。

  HashMap底层数组默认大小为16,这种存储位置又叫做桶(bucket),默认负载极限为0.75,即当HashMap中填满3/4时,

  HashMap的容量将自动增加一倍。这个过程中,元素会重新分配,放入新的桶中。这个过程叫做rehashing.



Java代码  收藏代码
public V put(K key, V value) { 
        if (key == null) 
            return putForNullKey(value); 
        int hash = hash(key.hashCode()); 
        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的put方法源代码 
 
static int indexFor(int h, int length) { 
     return h & (length-1); 
   } 
可以看到:1、元素的hash值是根据key的hashCode计算的。
       2、索引是根据元素的hash值简易计算的。

查询过程:与存储过程类似,先根据hashCode()返回值计算数组索引,若数组所在位置已经有元素,与栈中所有元素equals比较,若相同,则返回。



Java代码  收藏代码
public V get(Object key) { 
        if (key == null) 
            return getForNullKey(); 
        int hash = hash(key.hashCode()); 
        for (Entry<K,V> e = table[indexFor(hash, table.length)]; 
             e != null; 
             e = e.next) { 
            Object k; 
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 
                return e.value; 
        } 
        return null; 
    } 
 
HashMap的get方法 
 所有参与计算hashCode()返回值的关键属性,都应用于作为equals()比较的标准。

  不应该给equals()和hashCode()方法的依赖属性提供注入方法,或者可以直接将其设置为final.

创建过程:除了默认的构造方法,HashMap还提供了指定初始容量、负载因子的构造器。



Java代码  收藏代码
public HashMap(int initialCapacity, float loadFactor) { 
        if (initialCapacity < 0) 
            throw new IllegalArgumentException("Illegal initial capacity: " + 
                                               initialCapacity); 
        if (initialCapacity > MAXIMUM_CAPACITY) 
            initialCapacity = MAXIMUM_CAPACITY; 
        if (loadFactor <= 0 || Float.isNaN(loadFactor)) 
            throw new IllegalArgumentException("Illegal load factor: " + loadFactor); 
        // Find a power of 2 >= initialCapacity 
        int capacity = 1; 
        while (capacity < initialCapacity) 
            capacity <<= 1; 
 
        this.loadFactor = loadFactor; 
        threshold = (int)(capacity * loadFactor); 
        table = new Entry[capacity]; 
        init(); 
    } 
 
HashMap构造方法源代码 




可以看到:1、初始容量最大为1<<30。不可以更大。

       2、初始容量必须为大于指定容量的最小的2的n次方值



二、TreeMap

TreeMap采用“红黑树”的排序二叉树来保存Map中的每个Entry。每个Entry为红黑树的一个节点。

所有的Entry总是根据key按指定的规则保持有序。

红黑树是一种自平衡二叉树,每个节点的值都大于或等于它的左子树中所有节点的值,都小于或等于它的右子树中所有节点的值。



三、WeakHashMap、IdentityHashMap

WeakHashMap每个key对象保存了实际对象的弱引用。

IdentityHashMap的实现机制与HashMap类似,只有当key1==key2时,才认为key1与key2相等。它不保证任何key-value对之间的顺序,

也不保证它们的顺序随时间的推移不变。



四、LinkedHashMap、Properties

LinkedHashMap是HashMap的子类,使用双向链表来维护entry的插入次序,迭代输出时,元素顺序与插入顺序一致。

Properties也是HashMap的子类,把Map对象和属性文件关联起来,把Map对象的key和value与属性文件的属性名和属性值关联起来。



五、EnumMap

1、EnumMap所有key必须是枚举类的枚举值。

2、在内部以数组实现,根据key自然排序。

3、不允许使用null作为key,允许使用null作为value

4、创建EnumMap时必须指定一个枚举类,将EnumMap与指定枚举类关联起来。

5、EnumMap是性能最好的Map



另:Map有一个values方法,返回一个集合对象,

  其实,这个Values集合对象并未盛装任何java对象,主要用来遍历map中的所有value值。

mao
分享到:
评论

相关推荐

    map总结,原理,使用

    ### Map 总结:原理与使用详解 #### 一、Map 概述 **Map** 是 C++ STL(Standard Template Library)中的一种关联容器,它主要用于存储键值对(Key-Value pairs)。Map 的特点在于它能高效地进行查找、插入和删除...

    Android Google Map 总结

    本总结将详细探讨Android Google Map的关键知识点,包括设置、集成、功能实现以及优化策略。 1. **集成Google Maps API** 首先,要在Android应用中使用Google Maps,需要在Google Developer Console中创建一个新的...

    Map遍历方法总结

    ### Map遍历方法总结 #### 一、引言 在Java编程中,`Map`是一种常用的集合类型,用于存储键值对数据。由于其高效的数据查找特性,在许多场景下都有广泛的应用。对于开发者来说,了解如何有效地遍历`Map`中的元素是...

    route-map不错的路由过滤总结

    Route-map不错的路由过滤总结 Route-map 是一种强大的路由过滤工具,常用于路由协议之间的重分布、Policy-Based Routing(PBR)和 Border Gateway Protocol(BGP)。本文将对 Route-map 的配置和应用进行详细的总结...

    map.toString()后转换成Map类型

    #### 五、总结 通过上述步骤,我们可以有效地将`Map`对象转换为字符串,并能够将字符串还原为原来的`Map`结构。这种方法不仅适用于简单的键值对数据,还可以扩展应用于更复杂的场景。在实际开发中,这种方法可以...

    rammap自动运行程序

    总结来说,RAMMap是一款强大的内存分析工具,通过Python等编程语言可以实现其自动化运行,从而更好地管理和优化系统的内存资源。了解如何正确配置和利用RAMMap的自动化功能,对于系统管理员和性能优化人员来说,是...

    std map容器用法总结

    在C++编程中,`std::map`是一个非常重要的关联容器,它提供了键值对(key-value pairs)的存储功能,常被用来实现字典或查找表的数据结构。`std::map`的主要特点是对每个键都唯一,且键值对中的键按照某种排序规则...

    java一键xml转map,一键map转xml工具类

    总结来说,`EasyXmlUtil`是一个实用的Java工具类,它封装了XML与Map之间的相互转换功能,使得开发者能方便快捷地处理这两种数据格式。通过理解和使用此类,可以提高开发效率,简化数据处理的复杂性。在项目中,只需...

    map_map_增删查改_STL_C++_

    总结,C++的STL`map`容器是处理键值对数据的强大工具,其增删查改操作高效且易于使用。学习并熟练掌握`map`的使用,能够显著提升C++编程的效率和代码质量。在实际编程中,我们应根据需求选择合适的容器,充分利用STL...

    对Map的key和value进行排序

    总结 对Map的key和value进行排序是Java编程中非常重要的一部分。我们可以使用TreeMap和Comparator来对Map中的key或value进行排序,以满足特定的业务需求。在实际应用中,我们需要根据不同的业务需求选择合适的排序...

    m_map用法详解.rar_M map_m_map_m_map sst_matlab世界地图_世界地图 MATLAB

    总结来说,m_map工具箱是MATLAB中绘制地图和进行地理数据分析的强大工具,它的易用性和灵活性使得科研人员和工程师在处理地球科学、环境研究等领域的问题时,能够更加高效和直观。通过深入了解和实践m_map的各种函数...

    常用MAP消息体结构说明.

    总结来说,MAP消息体结构是MAP协议的核心组成部分,它们定义了不同业务的交互格式,确保了移动通信网络中移动性管理和呼叫处理的顺利进行。每个消息体包含的字段都有特定的含义,用于传递必要的控制信息,如身份、...

    java xml和map互转

    总结,使用DOM4J库,我们可以方便地在Java中实现XML与Map之间的互转。这不仅适用于简单的键值对,还支持嵌套结构、属性以及有无根节点的情况。在实际项目中,可以根据具体需求对这些方法进行适当的调整和优化。

    集合Collection和Map的总结

    这是对集合的总结,可以帮助我们对集合更深入更清晰的认识。

    map用法总结

    ### 总结 `Map`是Java编程中不可或缺的数据结构,了解并熟练掌握其各种操作和应用,对于提高代码质量和性能具有重要意义。通过本文的介绍,相信你已经掌握了`Map`的基本用法及一些高级特性,能够灵活运用到实际开发...

    MapServer MapServer 7.2.2文档

    总结,MapServer 7.2.2是WebGIS开发的重要工具,其强大的地图处理能力、丰富的API接口和灵活的配置选项,使得开发者能够构建高效、个性化的地图应用。通过深入理解和熟练运用MapServer,可以为地理信息系统的开发...

    map遍历的四种方法

    ### Map遍历的四种方法 ...### 总结 通过以上四种遍历`Map`的不同方式,我们可以根据具体的应用场景选择最适合的方法。在实际开发过程中,理解和灵活运用这些遍历技巧对于提高代码质量和效率具有重要意义。

    读取properties返回map并写入文件

    总结来说,读取.properties文件并将其内容转化为Map对象,以及将Map对象写回文件的过程,是Java开发中的常见操作。这使得我们可以方便地管理配置信息,并允许在不同环境间灵活切换配置。在实际项目中,可以进一步...

    将Map转换成Java实体

    总结起来,将Map转换为Java实体对象是Java开发中常见的需求,我们可以利用Core Java JDK 1.8的泛型和反射来实现这一功能。通过创建一个通用的工具类,我们可以简化代码并提高代码复用性。在使用过程中,需要注意处理...

Global site tag (gtag.js) - Google Analytics