目 录
HashMap集合(非线程安全的)
- HashMap集合底层是哈希表/散列表的数据结构(哈希表是一个数组和单向链表的结合体)
- HashMap底层有三个值:hash key value next
(哈希表:是一个一维数组,数组中每个元素是一个单链表)
两个重要方法put、get(重点)
两个重要方法put、get
存:map.put(k,v)实现原理:(掌握)
第一步:先将k,v封装到Node对象中
第二步:底层会调用k的hashCode()方法得出hash值,然后通过哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。如果下标对应位置上有链表,此时会拿着k和链表上每页节点的k进行equals,如果所有的equals方法返回的都是false,那么这个新节点被添加到这个链表的的末尾。如果其中有一个equals返回的true,那么这个节点value将会被覆盖
取:v=map.get(k)实现原理:(掌握)
先调用k的hashCode()方法得出哈希值,通过哈希算法转换成数组下标,通过数组下标快速定位到某个位置上,如果这个位置上什么也没有,返回null。如果这个位置上有单链表,那么会拿着参数k和链表上每个节点的k进行equals,如果所有的equals都返回false,那么这个get方法返回null。只要其中有一个k返回true,那么此时这个节点的value就是我们要找的value,get方法最终返回这个节点的value
代码实例:
public class HashMapTest01 {
public static void main(String[] args) {
Map<Integer,String> map=new HashMap<>();
//put方法
map.put(11,"qwe");
map.put(22,"asd");
map.put(33,"zxc");
map.put(22,"jkl");
//get方法
System.out.println(map.get(1));//qwe
//遍历方法一:(这种对于元素很多的时候效率高)
//先将Map转成Set
Set<Map.Entry<Integer,String>> set=map.entrySet();
//foreach遍历
for (Map.Entry<Integer,String> entry:set) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
//遍历方法二:
//先找key,通过key遍历value
Set<Integer> set1=map.keySet();
Iterator<Integer> iterator=set1.iterator();
while (iterator.hasNext()){
Integer key=iterator.next();
String value=map.get(key);
System.out.println(value);
}
}
}
为什么哈希表的随机增删、查询效率都高?
答:因为增删实在链表上完成,查询只是部分查询。
HashMap集合的部分特点
特点:无序,不可重复
为什么无序?
因为元素不一定挂到哪个单链表上
不可重复是怎么保证的?
equals方法保证了HashMap的key不可重复,如果key重复了,value会被覆盖
HashMap的初始化默认容量
初始化默认容量为16,加载因子为0.75f(数组达到75%开始扩容)(Hashset也同样)
扩容后为原容量的:2倍
(注意:HashMap初始化容量为2的倍数)
关于HashMap的equals方法和hashCode方法
放在HashMap集合key部分的元素其实都是放在HashSet集合中了,所以HashSet集合中的元素也需要同时重写hashCode()+equals()方法。
(Tip:如果hashCode()返回是一个固定值,就变成单链表了;如果返回值都不同,就变成一位数组了)
总结:放在HashMap集合的key部分,以及放在HashSet集合中的元素,hashCode()和equals都需要重写!
(注意:如果一个equals重写了,所对应的hashCode也必须重写。
并且如果equals返回的true,hashCode必须返回相同的值)
拓展
JDK8之后,HashMap的单向链表元素超过8个之后,该单链表会转换成红黑树,若红黑树中元素小于6个,会转换成单链表(为了提高检索效率)。
对于哈希表数据结构来说:
如果两个元素的hash值相同,一定是在同一个单链表上;
如果两个元素的hash值不相同,但由于哈希算法执行结束之后转换的数组下标可能
相同,此时会发生“哈希碰撞”。
Hashtable集合(线程安全的)
Hashtable和HashMap底层都是哈希表数据结构
Hashtable(带有synchronized:线程安全的)(使用较少)
HashTable和HashMap的部分区别
HashTable的key和value都不能为null
HashMap的key和value都可以为null(注意:顶多只能有一个key是null)
HashTable的初始化容量
初始化容量为11,默认加载因子是0.75f
扩容后为原容量的:2倍+1
Properties
Properties是一个Map集合,继承Hashtable
Properties的key和value都是String类型
Properties被称为属性类对象
Properties是线程安全的
Properties代码实例:
public class PropertiesTest01 {
public static void main(String[] args) {
//创建Properties对象
Properties pro=new Properties();
//存
pro.setProperty("a","123");
pro.setProperty("b","456");
pro.setProperty("c","789");
//取
System.out.println(pro.getProperty("a"));
System.out.println(pro.getProperty("b"));
System.out.println(pro.getProperty("c"));
}
}
/*
输出结果:
123
456
789
*/
来源:oschina
链接:https://my.oschina.net/u/4312121/blog/4303367