java集合类源码分析之Map(二)

时间:2021-10-05 09:20:08

这一节主要讨论Map接口的几个实现类的区别和用法。

1.线程安全

Hashtable是线程安全的(与Stringbuffer、Vector相似),而其他的都不是,至于为什么,可以看之前的一些文章,前面已经介绍地很详细了。

2.适用条件

HashMap:适用于需要快速查找的数据,并且数据无序的情况下,允许键为空(只一次),允许值为空;

TreeMap:适用于按key有序存储的数据,不允许键为空;

Hashtable:适用于有同步要求的情况下,保证线程安全,不允许键和值为空;

LinkedHashMap:保存了元素插入时的顺序,具有HashMap的所有特性,但遍历时比HashMap要慢。

HashMap与LinkedHashMap的比较示例:

 1     private static void linkedHashMapAnal() {
2 //LinkedHashMap具有HashMap的所有特性,并且能够保留元素插入时的顺序
3 Map<String, Integer> linkedHashMap = new LinkedHashMap<String, Integer>();
4 Map<String, Integer> hashMap = new HashMap<String, Integer>();
5
6 hashMap.put("A", 120);
7 hashMap.put("B", 100);
8 hashMap.put("C", 105);
9 hashMap.put("D", 200);
10 for(String key: hashMap.keySet()){
11 System.out.print(key+":"+hashMap.get(key)+" ");
12 }//D:200 A:120 B:100 C:105
13
14 System.out.println();
15 linkedHashMap.put("A", 120);
16 linkedHashMap.put("B", 100);
17 linkedHashMap.put("C", 105);
18 linkedHashMap.put("D", 200);
19 for(String key: linkedHashMap.keySet()){
20 System.out.print(key+":"+linkedHashMap.get(key)+" ");
21 }//A:120 B:100 C:105 D:200
22 }

 

3.排序问题

Map集合的排序常常分为按key排序和按value排序。

  • 按key排序

有两种方式来实现Map的按key排序:TreeMap中的比较器和Collections类中的sort方法。

1.TreeMap的按key排序

1         //采用默认比较器按key值升序排列,进行存储
2 Map<String, Integer> treeMap = new TreeMap<String, Integer>();
3 treeMap.put("B", 120);
4 treeMap.put("C", 105);
5 treeMap.put("A", 100);
6 for(String key: treeMap.keySet()){
7 System.out.print(key+":"+treeMap.get(key)+", ");
8 } //A:100, B:120, C:105,
9 }
 1         //自定义比较器,实现降序存储
2 Map<String, Integer> treeMap = new TreeMap<String, Integer>(new Comparator<String>() {
3 @Override
4 public int compare(String o1, String o2) {
5 // return 0; 默认升序
6 return o2.compareTo(o1); //降序
7 }
8 });
9 treeMap.put("B", 120);
10 treeMap.put("C", 105);
11 treeMap.put("A", 100);
12 for(String key: treeMap.keySet()){
13 System.out.print(key+":"+treeMap.get(key)+", ");
14 } //C:105, B:120, A:100,
 1         //用SortedMap子集初始化TreeMap对象,调用参数自带的比较器
2 //注意:此处参数必须为SortedMap类型及其子类或者实现类,否则将调用默认比较器,所以此处也可以创建一个TreeMap类型的subMap
3 SortedMap<String, Integer> subMap = new TreeMap<String, Integer>(new Comparator<String>() {
4
5 @Override
6 public int compare(String o1, String o2) {
7 // TODO Auto-generated method stub
8 return o2.compareTo(o1);
9 }
10 });
11 subMap.put("B", 100);
12 subMap.put("F", 120);
13 subMap.put("D", 105);
14 for(String key: subMap.keySet()){
15 System.out.print(key+":"+subMap.get(key)+", ");
16 } //F:120, D:105, B:100,
17
18 System.out.println();
19
20 Map<String, Integer> treeMap = new TreeMap<String, Integer>(subMap);
21 for(String key: treeMap.keySet()){
22 System.out.print(key+":"+treeMap.get(key)+", ");
23 } //F:120, D:105, B:100,
24
25 System.out.println();
26
27 treeMap.put("A", 200);
28 treeMap.put("C", 300);
29 treeMap.put("E", 400);
30 for(String key: treeMap.keySet()){
31 System.out.print(key+":"+treeMap.get(key)+", ");
32 } //F:120, E:400, D:105, C:300, B:100, A:200,

2.HashMap的按key排序

 1         //用HashMap子集初始化TreeMap对象,调用默认比较器(升序)
2 //此处参数为Map接口的实现类
3 Map<String, Integer> subMap = new HashMap<String, Integer>();
4 subMap.put("B", 100);
5 subMap.put("A", 120);
6 subMap.put("C", 105);
7 subMap.put("D", 200);
8 for(String key: subMap.keySet()){
9 System.out.print(key+":"+subMap.get(key)+", ");
10 } //D:200, A:120, B:100, C:105,
11
12 System.out.println();
13
14 Map<String, Integer> treeMap = new TreeMap<String, Integer>(subMap);
15 for(String key: treeMap.keySet()){
16 System.out.print(key+":"+treeMap.get(key)+", ");
17 } //A:120, B:100, C:105, D:200,
 1         Map<String, Integer> hashMap = new HashMap<String, Integer>();
2
3 //hashMap默认按key的哈希值排列,是一种无序存储
4 hashMap.put("A", 100);
5 hashMap.put("B", 120);
6 hashMap.put("C", 105);
7 hashMap.put("D", 100);
8 for(String key: hashMap.keySet()){
9 System.out.print(key+":"+hashMap.get(key)+" ");
10 }//D:100 A:100 B:120 C:105
11
12 System.out.println();
13 //将HashMap对象存储到List集合中
14 ArrayList<Map.Entry<String, Integer>> mapList = new ArrayList<Map.Entry<String, Integer>>(hashMap.entrySet());
15 //调用Collections的sort方法
16 Collections.sort(mapList, new Comparator<Entry<String, Integer>>() {
17
18 @Override
19 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
20 // TODO Auto-generated method stub
21 return o1.getKey().compareTo(o2.getKey());//升序
22 // return o2.getKey().compareTo(o1.getKey());//降序
23 }
24 } );
25
26 for (int i = 0; i < mapList.size(); i++) {
27 System.out.print(mapList.get(i).getKey()+":"+mapList.get(i).getValue()+" ");
28 }//A:100 B:120 C:105 D:100
  • 按value排序

有了上面的例子,我们知道也可以通过Collections的sort方法来进行Map集合的value排序,包括HashMap和TreeMap。

 1         Map<String, Integer> hashMap = new HashMap<String, Integer>();
2
3 hashMap.put("A", 100);
4 hashMap.put("B", 120);
5 hashMap.put("C", 105);
6 hashMap.put("D", 110);
7 for(String key: hashMap.keySet()){
8 System.out.print(key+":"+hashMap.get(key)+" ");
9 }//D:110 A:100 B:120 C:105
10
11 System.out.println();
12 //将HashMap对象存储到List集合中
13 ArrayList<Map.Entry<String, Integer>> mapList = new ArrayList<Map.Entry<String, Integer>>(hashMap.entrySet());
14 //调用Collections的sort方法
15 Collections.sort(mapList, new Comparator<Entry<String, Integer>>() {
16
17 @Override
18 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
19 // TODO Auto-generated method stub
20 return o1.getValue().compareTo(o2.getValue());//升序,按value排序只需将getKey换成getValue即可
21 // return o2.getValue().compareTo(o1.getValue());//降序,按value排序只需将getKey换成getValue即可
22 }
23 } );
24
25 for (int i = 0; i < mapList.size(); i++) {
26 System.out.print(mapList.get(i).getKey()+":"+mapList.get(i).getValue()+" ");
27 }//A:100 C:105 D:110 B:120
 1         ArrayList<Map.Entry<String, Integer>> mapList = new ArrayList<Map.Entry<String, Integer>>(treeMap.entrySet());
2 Collections.sort(mapList, new Comparator<Entry<String, Integer>>() {
3
4 @Override
5 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
6 // TODO Auto-generated method stub
7 return o1.getValue().compareTo(o2.getValue());//升序
8 // return o2.getValue().compareTo(o2.getValue());//降序
9 }
10 });
11 for (int i = 0; i < mapList.size(); i++) {
12 System.out.print(mapList.get(i).getKey()+":"+mapList.get(i).getValue()+" ");
13 }//B:100 D:105 F:120 C:300 E:400 A:500
14
15 }