Map
Map(双列集合)
|-------Map
|---------HashMap(主要实现类,底层是hash表 - 线程不安全的)
|-----------LinkedHashMap(可以按照添加元素的顺序进行排序)
|---------Hashtable(底层也是hash表 不过是线程安全的)
|-----------Properties(主要读取配置文件-后面讲)
|---------TreeMap(用来对key进行排序)
说明:
1.Map中存放的是键值对
2.Map中常用的实现类有 :HashMap LinkedHashMap Hashtable TreeMap Properties
3.Map中的元素是无序的
4.key不可重复(如果重复value覆盖-后面的覆盖前面的) value可重复
5.如果map中的key是自定义类的对象那么必须重写hashCode方法和equals方法。
因为往map中存放的对象会通过hashCode方法得到哈希值再通过该哈希值计算存储的位置。
equasl方法-如果同一个位置已经存在对象那么需要通过equals判断是否一样
(如果为true说明key值相同-key值相同会value覆盖 否则说明key值不同)
6.如果map中的value是自定义类的对象必须重写equals方法
为什么不用重写value的hashCode方法 - 在map中是通过key确定位置的 和 value没有关系
HashMap
说明:
1.HashMap的底层是Hash表(数组 + 链表 + 红黑树)
2.HashMap的构造器 :通过空参构造器创建对象时给加载因子赋值0.75
3.第一次添加数据时 : 当第一次添加时底层会创建一个长度为16的数组(Node类型的数组)
阈值是12 = 加载因子 * 数组的长度(当数组中的元素的个数超过阈值就会扩容)
4.底层扩容(第1次) :当我们向集合中添加第13个元素时底层会进行扩容。
数组的长度为原来的2倍阈值为原来的2倍。同时将原来的hash表中的数据copy到新的hash表中。
5.向集合中存放数据流程
当我们向集合中存放数据(k1,v1)时首先会先通过k1的hashCode方法算出哈希值通过哈希值计算出要在数组中
存放的位置。如果该位置没有其它元素直接放入。如果该位置已经存在其它元素(K,V)时那么就会调用
K1的equals方法和K进行比较如果返回值为true说明key值相同V1覆盖V。
如果返回值为false
(
要和链表中每一个值equals对比直到最后
如果在和链表上的数据比较时返回true那么value则直接覆盖 ,
如果比到最后都是false则以链表的形式连上去
)
则以链表的形式直接连上去
6. 链表什么时候转成红黑树?
当链表上的元素个数达到9时并且数组的长度要>=64那么会将链表转成红黑树
LinkedHashMap
LinkedHashMap :LinkedHashMap是HashMap的子类。LinkedHashMap的底层实现和HashMap的底层实现是一样的。
LinkedHashMap中维护一张链表用来记录元素添加的顺序
(HashMap的底层是Node[] LinkedHashMap底层是Entry[] - Entry是Node的子类)。
Hashtable
[面试题]HashMap和Hashtable的区别?
1.HashMap是线程不安全的 Hashtable是线程安全的 (重要)
2.HashMap和Hashtable底层都是Hash表
3.HashMap的空参构造器中只给加载因子赋值0.75 (第1次创建的数组长度为16-Node[] 阈值是12)
Hashtable的空参构造器中创建了一个长度为11的Entry[] 加载因子0.75 阈值是8
4.Hashtable中的key,value不能是null (重要)
HashMap中的key,value可以是nulll
5.HashMap扩容为原来的2倍。Hashtable扩容为原来的2倍+1
Properties:
1.Properties是Hashtable的子类
2.Properties是一个Map
3.Properties中的key和value都是String类型
4.Properties可以用来读取配置文件(IO流再说)
TreeMap :
说明:
1.TreeMap的底层是红黑树(TreeSet)
2.TreeMap用来对数据排序 -- 只能对key排序
3.TreeMap对key的排序方式 : 自然排序 vs 定制排序
4.TreeMap中key的类型要保持一致。
TreeSet的底层是TreeMap
HashSet的底层是HashMap
LinkedHashSet的底层是LinkedHashMap
注意:Set的底层是Map。 Set的特点是Map的key的特点
定制排序和自然排序都有的情况下 定制排序生效
public class MapTest6 {
@Test
public void test(){
LinkedHashSet<Object> set = new LinkedHashSet<>();
set.add("a");
}
@Test
public void test2(){
TreeMap<Emp, Integer> map = new TreeMap<>(new Comparator<Emp>() {//定制排序
@Override
public int compare(Emp o1, Emp o2) {
return o1.sal - o2.sal;
}
});
map.put( new Emp(2300,11) , 5);
map.put( new Emp(4000,15) , 3);
map.put( new Emp(3600,13) , 4);
map.put( new Emp(5000,12) , 9);
System.out.println(map);
}
}
class Emp implements Comparable<Emp>{//自然排序
int sal;
int id;
public Emp(int sal,int id) {
this.sal = sal;
this.id = id;
}
@Override
public int compareTo(Emp o) {
return this.id - o.id;
}
@Override
public String toString() {
return id + " " + sal;
}
}