Map
Map是集合框架中的另一个顶层接口,Map中的元素是成对出现的,形式是<key,value>,key是不重复,每个 key对应一个value ;
1.常用的方法;
isEmpty();
clear();
put();
putAll();
containsKey();
containsValue();
remove();
get();
size();
keySet();键的集合
values();值 的集合
entrySet();键值对的集合
2.HashMap
Map 的最常用的实现类;
Map<String,Book> map=new HashMap<String,Book>();
3.遍历Map的三种方方式
//1.遍历集合的第一种方式,先获得key的集合,这个集合的类型是Set,通过keySet()方法获得key的集合
Set<String> keys=map.keySet();
System.out.println(keys);
for(String s:keys) {
System.out.println(s+":"+map.get(s));
}
//2.第二种方式,是只遍历value,通过values方法获得所有value的集合,类型是Collection
Collection<Book> books=map.values();
for(Book b:books) {
System.out.println(b);
}
//3.第三种方式,通过entrySet来获得键值对的集合;
Set<Entry<String,Book>> sets=map.entrySet();
for(Entry<String,Book> e:sets) {
System.out.println(e.getKey()+":"+e.getValue());
}
entry是Map的内部类,是键值对的封装
4.java8中Map新方法
1)putIfAbsent();若不存在相应键值对,则执行map.put,若存在,则不会进行操作。(put方法会直接覆盖)
V v = map.get(key); if (v == null) v = map.put(key, value); return v;
2)remove增加了一个重载方法,需要传两个参数,键值对应匹配则删除,否则不删除。
3)replace同样增加一个重载方法,需要传三个参数,若原键值匹配才将新值替换进去。
5.HashMap源码分析
Node类,此类实现Map.Entry接口,此类是对key,和value的封装;同时它也是一个单向链表;
它的属性有;
hash;哈希值
key :键
value:值
next: 下一个节点的引用;
属性:
size:元素个数
loadfactor:加载因子,默认为0.75;当(元素的个数/数组长度超)过这个值是,将会扩容;
table:内部用来存储键值(Node)对的数组;
构造方法:
():初始长度16,加载因子是0.75
(int):指定初始长度; 建议2的次方
(int,double);指定初始长度和加载因子
(map):有初始值;
方法;
put(key,value):
重新计算hash值
判断容量是否扩容,并完成扩容
计算存储位置; (table.legth-1)&hash == hash%table.legth;
存储新元素
如果此位置没有元素,直接存到此位置
如果此位置的key与新key相等,替换
如果不相等,则遍历单向链表;
具体源码分析可参考:
https://www.cnblogs.com/xiaoxi/p/7233201.html
6.Hashtable(哈希表)
早期版本遗留的Map实现,它Dictinary类;
Hashtable是线程安全的,而HashMap是线程不安全;
对于null来说,HashMap支持null(key,value),而Hashtable不支持null
7.TreeMap
TreeMap是SortedMap的实现类,它具备了排序功能;TreeMap中的元素(Key)按照Comparable或Comparator进行排序;
TreeMap内部是一个红黑树(平衡二叉树)
TreeMap源码
内部类
Entry
K 键
V value
parent :父元素
left: 左子元素
right:右子元素
属性;
comparator:比较器
size:元素的个数
root:根元素
方法:
put方法
找到root元素,判断是否为null,如果为null,将些元素赋给root;
如果root不为空,获得comparator,如果comparator不会 null,使用比较器进行,否则用comparable进行比较
与entry进行比较,如果<0,找left进行比较,如果>0,与rigth进行比较,如果=0,给entry 的value重新赋值
重复步骤3,直到entry为null,将此元素放到此节点中;