java基础学习之集合-Map

本文介绍了Java中的Map接口,重点关注HashMap的结构、存储原理、遍历方式,还对比了Hashtable的线程安全和TreeMap的排序特性,以及Properties的使用。
摘要由CSDN通过智能技术生成

java中的Map集合是一个由键-值(key-value)组合而成的,Map作为一个接口,jdk解释为将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map.entry是其内部的一个接口,由于Map没有实现Iterable接口,就不能使用iterator来遍历集合,所以通过entrySet方法转换为Set,这个Set里存放每个元素都是一个 Map.Entry< K , V >再来遍历这个Set即可。

一.HashMap介绍

HashMap 是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

可以看出HashMap继承了AbstractMap,实现了Map,Cloneable,Serializable接口,这里没有实现同步,所以它是线程不安全的,这里可以在创建是通过Collections的集合工具类方法来实现同步。

Map m = Collections.synchronizedMap(new HashMap(...));

HashMap的构造器:

// 默认构造函数。
HashMap()

// 指定“容量大小”的构造函数
HashMap(int capacity)

// 指定“容量大小”和“加载因子”的构造函数
HashMap(int capacity, 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);

        this.loadFactor = loadFactor;
        //threshold 临界值   当实际大小超过临界值时,会进行扩容threshold = 加载因子*容量
        threshold = initialCapacity;
        init();
}

// 包含“子Map”的构造函数
HashMap(Map<? extends K, ? extends V> map){
    inflateTable(threshold);
    putAllForCreate(m);
}

二.HashMap结构

hashMap是一个散列表,通过“拉链法”来解决hash冲突

它是基于数组和链表实现的,从上面构造器的方法可以看到容量大小(capacity)和加载因子(loadFactor)两个参数对hashMap非常重要,容量指的是哈希表中桶的数量,初始容量是创建哈希表时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。系统默认负载因子为0.75,这个值应该是比较均衡的值。若哈希表中元素超过了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
在一个长度为16的数组中,每个数组的元素都是存储一条链表的头节点,hashmap通过对元素的key的hash值对数组的长度取模来得到这个元素应该位于数组的那个位置,hash(key)% len,比如12%16=12,28%16=12,这样12和28都会位于数组下标为12的链表中。那这个链表又如何实现的呢?
HashMap数据存储数组:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值