概述
先上一张JAVA集合继承关系图:
使用Map时,用得最多的是HashMap
Map<String, String> hashMap = new HashMap<String, String>();
但是HashMap是无序的,既不保证元素按插入顺序性,也不保证元素按给定的排序方法按大小进行排序。
HashMap无序
HashMap的底层实现是哈希映射,所以表现为Hash的特点,不具有有序性
代码实例
public class Test {
public static void main(String[] args) throws Exception {
Map<String, String> hashMap = new TreeMap<>();
hashMap.put("a1", "6");
hashMap.put("b1", "9");
hashMap.put("d1", "8");
hashMap.put("c1", "7");
Iterator<Map.Entry<String , String >>iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, String> entry = iterator.next();
System.out.println("key " + entry.getKey() + " --- value " + entry.getValue());
}
}
}
输出结果
key a1 --- value 6
key b1 --- value 9
key c1 --- value 7
key d1 --- value 8
可以看出HashMap既没有插入顺序性,也不具有大小上的顺序性
有序Map
那么有没有Map能保证有序性呢?答案是有
下面分别从插入顺序有序性和大小顺序分析有序Map
LinkedHashMap按插入顺序保证有序性
LinkedHashMap是继承于HashMap,是基于HashMap和双向链表来实现的,看到双向链表,应该不难理解为何LinkedHashMap能够维护插入顺序了吧
LinkedHashMap按插入顺序进行排序:
public class Test {
public static void main(String[] args) throws Exception {
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("a1", "6");
linkedHashMap.put("b1", "9");
linkedHashMap.put("d1", "8");
linkedHashMap.put("c1", "7");
Iterator<Map.Entry<String , String >>iterator = linkedHashMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, String> entry = iterator.next();
System.out.println("key " + entry.getKey() + " --- value " + entry.getValue());
}
}
}
输出结果
key a1 --- value 6
key b1 --- value 9
key d1 --- value 8
key c1 --- value 7
从输出结果可以看出,LinkedHashMap维护了元素的插入顺序
另外:LinkedHashMap还有一个比较强的功能,按访问顺序排序,如果在创建LinkedHashMap的时候将accessOrder设为true,那么LinkedHashMap也有访问顺序,就是说你访问了一个key,这个key就跑到了最后面,如果是访问顺序,那put和get操作已存在的Entry时,都会把Entry移动到双向链表的表尾(其实是先删除再插入)。
TreeMap按插入顺序保证有序性
与HashMap相比,TreeMap是一个能比较元素大小的Map集合,会对传入的key进行了大小排序。其中,可以使用元素的自然顺序,也可以使用集合中自定义的比较器来进行排序;
不同于HashMap的哈希映射,TreeMap底层实现了红黑树的结构,。至于什么是红黑树,这里就不多讲了。
public class Test {
public static void main(String[] args) throws Exception {
Map<Integer, String> map = new TreeMap<>();
map.put(6, "6");
map.put(9, "9");
map.put(8, "8");
map.put(7, "7");
Iterator<Map.Entry<Integer , String >>iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<Integer, String> entry = iterator.next();
System.out.println("key " + entry.getKey() + " --- value " + entry.getValue());
}
}
}
输出结果如下:
key 6 --- value 6
key 7 --- value 7
key 8 --- value 8
key 9 --- value 9
总结
HashMap结构更简单,内存小,效率更高
TreeMap可以维护大小顺序
LinkedHashMap则可以维护插入顺序和访问顺序
可以看出,TreeMap默认使用元素的自然顺序
参考文章:
【1】https://www.jianshu.com/p/2dcff3634326