Map
- Map和Collection没有继承关系
- Map集合以key和value的方式存储数据:键值对
key和value都是引用数据类型
key和value都是存储对象的内存地址
key起到主导的地位,value是key的一个附属品 - Map接口的常用方法:
V put(k key, V value): 向Map中添加键值对
v get(Object key): 通过key获取value
void clear(): 清空Map集合
boolean containsKey(Object key): 判断Map是否包含某个key
boolean containsValue(Object value): 判断Map是否包含某个value
boolean isEmpty(): 判断Map集合中元素个数是否为0
Set< K > keySet(): 获取Map集合所有的key
V remove(Object key): 通过key删除键值对
int size(): 获取Map集合中键值对的个数
Collection< V > values(): 获取Map集合中所有的value,返回一个Collection
Set< Map.Entry<k,v>> entrySet(): 将Map集合转换成Set集合
public class MapTest01 {
public static void main(String[] args) {
//创建一个Map集合对象
Map<Integer, String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan");
map.put(2,"lisi");
map.put(3,"wangwu");
map.put(4,"zhaoliu");
//通过key获取value
String s = map.get(1);
String s1 = map.get(2);
String s2 = map.get(3);
String s3 = map.get(4);
System.out.println(s);
//获取键值对的数量
System.out.println("键值对的数量是:"+map.size());
//通过key删除键值对
map.remove(2);
System.out.println("键值对的数量是:"+map.size());
//判断是否包含key
System.out.println(map.containsKey(4));
//判断是否包含某个value
System.out.println(map.containsValue("zhaoliu"));
//获取所有的value
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
//清空Map
map.clear();
System.out.println("键值对的数量是:"+map.size());
//判断是否为空
System.out.println(map.isEmpty());
}
}
HashMap集合
- HashMap集合底层是哈希表/散列表的数据结构。
- 哈希表是一个怎样的数据结构?
哈希表是一个数组和单向链表的结合体。
数组:在查询方面效率很高,随机增删方面效率很低。
单向链表:在随机增删方面效率高,在查询方面效率低。
哈希表将以上两种数据结构融合在了一起,发挥他们各自的有点。 - HashMap集合底层的源代码:
public class HashMap{
//HashMap底层实际上就是一个数组。(一维数组)
Node<k,v>[] table;
//静态的内部类HashMap.Node
static class Node<K,V>{
final int hash;//哈希值(哈希值是key的hashCode()方法的执行结果。hash值通过哈希函数/算法,可以生成下标)
final k key;//储存到Map集合中的那个key
v value;//储存到Map集合的那个value
Node<k,v> next;//下一个节点的内存地址
}
}
map.put(k,v)实现原理:
- 第一步:先将k,v封装到Node对象中。
- 第二步:底层会调用k的hashCode()方法得出hash值。
- 第三步:通过哈希函数/算法,将Hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。
- 第四步:如果下标位置上有链表,此时会拿着k和链表上每一个节点中的k进行equals,如所有的equals方法返回的都是false,那么这个新节点将被添加到链表的末尾。如果其中有个equals返回了true,那么这个节点的value就会被覆盖。
map.get< k >实现原理:
- 先调用k的hashCode()方法得出哈希值,通过哈希算法转换成数组下标,通过数组下标快速定位到某个位置上,如果这个位置上什么东西都没有,返回null,如果这个位置上有单向链表,那么会拿着参数k和单向链表上的每个节点中的k进行equals,如果所有equals方法返回false,那么get方法返回null,只要其中有一个节点的k和参数k,equals的时候返回true,那么此时这个节点的value就是我们要找的value,get方法最终返回这个要找的value。