[2025.1.12 JavaSE学习]集合-5(HashMap接口特点 && 存储底层源码分析)

jdk8版本Map接口

  • Map和Collection并列存在,用于保存具有映射关系的数据:Key-Value
  • Map中的Key和Value可以是任何引用类型的数据,会封装到HashMap$Node对象中
  • Map中的Key不允许重复(与之前HashSet一样,底层源码中HashSet的元素就是HashMap的key
  • Map中的value可以重复
  • Map的key可以为null,value也可以为null
  • 常用类String可以作为key
  • key和value存在单向一对一关系,指定的key可以找到对应的value
  • 使用put压入两个相同的key时,后面的key对应的value会替换前面的
  • HashMap线程不安全,无synchronized修饰

存储源码分析

  • 底层的Node实现了Map.Entry接口(此处和上一节LinkedHashMap&Entry不同。后者是内部类,为HashMap.Node的子类)
//HashMap.java
static class Node<K,V> implements Map.Entry<K,V>{
	final int hash;
	final K key;
	V value;
	Node<K,V> next;
	......
}

存储原理

  • 底层上,一对key-value是存储在HashMap的Node
HashMap$Node node = new Node(hash, key, value, null);
  • 为了便于程序员遍历,还会创建EntrySet集合,该集合存放的元素类型:Entry
  • 而一个Entry对象就有key-value:Set<Map.Entry<K,V>>entrySet;
  • 在Entry中,让key指向Node中的key,value指向Node中的value(为了方便遍历)
  • HashMap中有内部类:HashMap$EntrySet:
Set set = map.entrySet();
system.out.println(set.getClass());//HashMap$EntrySet
  • entrySet中定义的类型是Map.Entry,但是实际上存放的还是HashMap$Node类型(只是实际位置不在这)(两者之间关系:Node实现了Map.Entry接口,当有一个类实现了接口,多态可以使用接口)
for(Object entry: set){
	System.out.println(entry.getClass());//HashMap$Node
}
  • Q:为什么这样便于遍历
  • A:因为Map.Entry提供了重要方法:
    • 1、getKey();
    • 2、getValue();
  • 遍历时用法:
for(Object obj:set){
	Map.Entry entry = (Map.Entry) obj;//先向下转型
	System.out.println(entry.getKey()+entry.getValue());
}
  • 也可以使用map.KeySet(),将Key单独封装到一个Set; 或使用map.values(),将value单独封装到一个Collection中
posted @ 2025-01-12 02:56  Luna-Evelyn  阅读(3)  评论(0)    收藏  举报