《知识点036:HashMap遍历的4种方法(4种)》

(一)HashMap类的介绍

HashMap是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在。

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

HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap,例如:Map map = Collections.synchronizedMap(new HashMap());

1.1:构造函数

1、在这里提到了两个参数:初始容量,加载因子。这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。

2、对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。系统默认负载因子为0.75,一般情况下我们是无需修改的。

HashMap():构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity, float loadFactor):构造一个带指定初始容量和加载因子的空 HashMap。

1.2:属性

transient Entry[] table;//存储元素的实体数组
transient int size;//存放元素的个数
int threshold; //临界值   当实际大小超过临界值时,会进行扩容threshold = 加载因子*容量
final float loadFactor; //加载因子
transient int modCount;//被修改的次数

1、其中loadFactor加载因子是表示Hsah表中元素的填满的程度.若:加载因子越大,填满的元素越多,好处是,空间利用率高了,但:冲突的机会加大了.链表长度会越来越长,查找效率降低。反之,加载因子越小,填满的元素越少,好处是:冲突的机会减小了,但:空间浪费多了表中的数据将过于稀疏(很多空间还没用,就开始扩容了)冲突的机会越大,则查找的成本越高.因此,必须在 "冲突的机会"与"空间利用率"之间寻找一种平衡与折衷. 这种平衡与折衷本质上是数据结构中有名的"时-空"矛盾的平衡与折衷. 如果机器内存足够,并且想要提高查询速度的话可以将加载因子设置小一点;相反如果机器内存紧张,并且对查询速度没有什么要求的话可以将加载因子设置大一点。不过一般我们都不用去设置它,让它取默认值0.75就好了。

1.3:方法

借鉴博主【我该去图书馆了】的一篇文章内容:

HashMap常用方法总结_hashmap方法-CSDN博客

HashMap常用方法:
1、put(K key, V value): 将键(key)/值(value)映射存放到Map集合中。

2、get(Object key): 返回指定键所映射的值,没有该key对应的值则返回 null。

3、size(): 返回Map集合中数据数量。

4、clear(): 清空Map集合。

5、isEmpty(): 判断Map集合中是否有数据,如果没有则返回true,否则返回false。

6、remove(Object key): 删除Map集合中键为key的数据并返回其所对应value值。

7、values(): 返回Map集合中所有value组成的以Collection数据类型格式数据。

8、containsKey(Object key): 判断集合中是否包含指定键,包含返回 true,否则返回false。

9、containsValue(Object value): 判断集合中是否包含指定值,包含返回 true,否则返回false。

10、keySet(): 返回Map集合中所有key组成的Set集合。

11、entrySet(): 将Map集合每个key-value转换为一个Entry对象并返回由所有的Entry对象组成的Set集合。

数据结构

Hashmap是一个数组和链表的结合体(在数据结构称“链表散列“),如下图示:

当我们往hashmap中put元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标),然后就可以把这个元素放到对应的位置中了。如果这个元素所在的位子上已经存放有其他元素了,那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。

1.4:例子

Map map = new HashMap();
map.put("Rajib Sarma","100");
map.put("Rajib Sarma","200");//The value "100" is replaced by "200".
map.put("Sazid Ahmed","200");

Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
    Map.Entry entry = (Map.Entry) iter.next();
    Object key = entry.getKey();
    Object val = entry.getValue();
}

1.5:总结

1、归纳起来简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,会根据 Hash 算法来决定其存储位置;当需要取出一个 Entry 时,也会根据 Hash 算法找到其存储位置,直接取出该 Entry。由此可见:HashMap 之所以能快速存、取它所包含的 Entry,完全类似于现实生活中母亲从小教我们的:不同的东西要放在不同的位置,需要时才能快速找到它。
2、当创建 HashMap 时,有一个默认的负载因子(load factor),其默认值为 0.75,这是时间和空间成本上一种折衷:增大负载因子可以减少 Hash 表(就是那个 Entry 数组)所占用的内存空间,但会增加查询数据的时间开销,而查询是最频繁的的操作(HashMap 的 get() 与 put() 方法都要用到查询);减小负载因子会提高数据查询的性能,但会增加 Hash 表所占用的内存空间。

(二)HashMap遍历的4种方法

第3种方式用得最多,但是如果hashmap的数据比较多,建议用第二种。

HashMap赋值如下:

Map<String, String> map = new HashMap<String, String>();  
map.put("1", "value1");  
map.put("2", "value2");  
map.put("3", "value3");

2.1:Iterator迭代遍历

//通过Map.entrySet使用iterator遍历key和value: 
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();  
while (it.hasNext()) {  
    Map.Entry<String, String> entry = it.next();  
    System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  
}

2.2:map循环遍历

//通过Map.entrySet遍历key和value,尤其是容量大时   
for (Map.Entry<String, String> entry : map.entrySet()) {  
    System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  
}

2.3:for循环遍历第一种方法

//通过Map.keySet遍历key和value,普遍使用,二次取值  
for (String key : map.keySet()) {  
    System.out.println("key= "+ key + " and value= " + map.get(key));  
}

2.4:for循环遍历第二种方法

//通过Map.values()遍历所有的value,但不能遍历key
for (String v : map.values()) {  
    System.out.println("value= " + v);   
}

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大大钢琴

喜欢!就请他吃3块钱好吃的吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值