JCF之Map
【摘要】JCF之Map[映射]~
前言
hi~
Map的存储方式
它不像Collection直接存储元素本身,而是通过key -> value的方式进行存储,也就是键、值对的映射。
如:
1 | Book b1 = ....; |
而利用Map存储:
1 | Map<Integer,Book> map = new HashMap<>(); |
注:
可以看出,Map通过key->value方式存储的效率更高,原因是map通过key[它只是对象的一小部份]来操作value。
所以,对于Map,最核心的就是Key,一般而言,key只会选择如下三种类型:
Integer
Long
String
因为,这三种类型都是API自带的,并且它们都是可比较的,也就是都实现了Comparable接口。
Map的特点:
key不允许重复。
它是无序的。
对于HashMap实现来说,允许null键和null值。
有关Map的API
1 | java.util.Map |
在Map中,可以通过key来获取value,但反过来不行。所以,Map中,对Key是有要求的【不允许重复、无序】。
Map的操作
put(K k, V value);
get(K k);
clear();
remove(K k);
putAll(Map<K,V> map);
size();
isEmpty();
…
如何迭代Map
首先,Map没有继承 Iterable接口,所以,不能使用foreach循环来迭代。
其次,也没有方法返回 Iterator 接口实例。
so, how?
由于Map由key-value组成,我们有理由从如下三个角度来看集合:
- 把Map的key单独取出来形成 Set。
1
2
3
4
5
6
7
8
9
10//Code:
Map<Integer, Book> map = ....;
//...
Set<Integer> keys = map.keySet();
//接下来就是迭代 Set
for(Integer key : keys) {
//再通key来获取 value
Book value = map.get(key);
//...
} - 把Map的value单独取出来形成 Collection。
1
2
3
4Collection<Book> values = map.values();
for(Book b : values) {
//...
} - 把Map的key和value都取出来形成 Set。
这需要把key和value封装成一个类型,才能存放到Set中,所以:1
Set<Entry<Integer,Book>> entry = map.entrySet();
SortedMap的实现类 TreeMap
我们使用此类的目的就是为了排序,而它同样支持两种排序的使用:
- 空参构造时使用 自然顺序,也就是要求Key的类型要实现 java.lang.Comparable接口。
- 以比较器为构造参数,也就是对Key的类型没有要求,但是要传入一个Comparator实例为参。
如:
1 | Map<Integer,Book> map = new TreeMap<>(); |
HashMap是如何保证Key不重复的?
答:调用Key的 hashcode方法,得到哈希码值,并由这个值来决定存放的位置。
当第二次放入对象时,同样会调用hashCode方法,得到哈希码值,会比较这个值所对应的位置,如果之前所存放的对象位置一样,则进一步调用equals方法。
如果equals为true,则表示key值一样,那只留下1个。
如果equals为false,则继续算出另一个位置来存放。
TreeMap是如何保证Key不复重的?
答:通过比较器或自然顺序,当通过空参构造时,则利用Comparable接口。
当通过带比较器参数来构造时,则利用Comparator接口。
TreeMap和HashMap的区别
答:有关hashCode方法和equals方法的原则:
1.equals方法返回true,则两个对象的hashcode值一定是一样的。
2.equals方法返回false,则尽最大努力保证它们的hashcode方法的返回值不一样。
HashSet 是如何保证元素唯一、无序的?
它的原理与HashMap是一模一样的,实际上,HashSet本身就是基于HashMap实现的,它组合了HashMap。
可以看一下HashSet的源码,片断如下:
1 | public class HashSet<E> implements Set<E> { |
TreeSet和TreeMap 的关系?
实际上,TreeSet组合了TreeMap,所以,它们的原理是一样的。
结束语
小结:
1 | 无序、不可重复 |
bye~