Java集合(6):理解Map
映射表的基本思想是维护键-值对的关联,通过键来寻找值。下面是标准Java类库中几种Map的实现:
(1) HashMap:Map基于散列表的实现,插入和查询键值对的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器性能。它是默认选择。
(2) LinkedHashMap:类似于HashMap,但是迭代遍历它时,取得的键值对的顺序是插入它的顺序,或者是最近最少使用(LRU)顺序,没有被访问过的元素会排在最前面,以便删除。比HashMap慢一点,而在迭代访问时反而更快,因为它使用链表维护内部次序。
(3) TreeMap:基于红黑树的实现。查询键或键值对时,它们会被排序,次序由实现Comparable接口的键或构造器参数Comparator<key>决定。TreeMap所得到的结果是经过排序的,TreeMap是唯一带有subMap()方法的Map,可以返回一个子树。
(4) WeakHashMap:弱键(weak key)映射,允许映射释放所指向的对象,这是为解决某类特殊问题而设计的。如果映射之外没有引用指向某个键,则此键可以被垃圾回收。
(5) ConcurrentHashMap:一种线程安全的Map,它不涉及同步加锁。
(6) IdentityHashMap:使用==代替equals()对键进行比较的散列映射。
下面是两个例子,分别举例了TreeMap和LinkedHashMap的用法。
1 import java.util.Iterator; 2 import java.util.TreeMap; 3 4 public class Test7 { 5 6 public static void main(String[] args) { 7 TreeMap<Integer, String> sortedMap = createMapData(); // 默认按照key排序,key必须实现Comparable接口 8 System.out.println(sortedMap); // {1=Beijing, 2=Shanghai, 3=Shenzhen, 4=Guangzhou, 5=Tianjin, 6=Nanjing, 7=Hangzhou, 8=Suzhou, 9=Chengdu, 10=Wuhan} 9 Integer low = sortedMap.firstKey(); 10 Integer high = sortedMap.lastKey(); 11 System.out.println(low); // 1 12 System.out.println(high); // 10 13 Iterator<Integer> it = sortedMap.keySet().iterator(); 14 for (int i = 0; i <= 6; i++) { 15 if (i == 4) 16 low = it.next(); 17 if (i == 6) 18 high = it.next(); 19 else 20 it.next(); 21 } 22 System.out.println(low); // 5 23 System.out.println(high); // 8 24 System.out.println(sortedMap.subMap(low, high)); // {5=Tianjin, 6=Nanjing, 7=Hangzhou} 25 System.out.println(sortedMap.headMap(high)); // {1=Beijing, 2=Shanghai, 3=Shenzhen, 4=Guangzhou, 5=Tianjin, 6=Nanjing, 7=Hangzhou} 26 System.out.println(sortedMap.tailMap(low)); // {5=Tianjin, 6=Nanjing, 7=Hangzhou, 8=Suzhou, 9=Chengdu, 10=Wuhan} 27 } 28 29 private static TreeMap<Integer, String> createMapData() { 30 TreeMap<Integer, String> result = new TreeMap<>(); 31 result.put(3, "Shenzhen"); 32 result.put(6, "Nanjing"); 33 result.put(1, "Beijing"); 34 result.put(9, "Chengdu"); 35 result.put(2, "Shanghai"); 36 result.put(10, "Wuhan"); 37 result.put(5, "Tianjin"); 38 result.put(7, "Hangzhou"); 39 result.put(4, "Guangzhou"); 40 result.put(8, "Suzhou"); 41 return result; 42 } 43 }
1 public class Test8 { 2 public static void main(String[] args) { 3 // 插入顺序 4 LinkedHashMap<Integer, String> linkedMap = createMapData(); 5 System.out.println(linkedMap); // {3=Shenzhen, 6=Nanjing, 1=Beijing, 9=Chengdu, 2=Shanghai, 10=Wuhan, 5=Tianjin, 7=Hangzhou, 4=Guangzhou, 8=Suzhou} 6 // LRU(初始容量, 负载因子, LRU flag) 7 linkedMap = new LinkedHashMap<Integer, String>(16, 0.75f, true); 8 linkedMap.putAll(createMapData()); 9 System.out.println(linkedMap); // {3=Shenzhen, 6=Nanjing, 1=Beijing, 9=Chengdu, 2=Shanghai, 10=Wuhan, 5=Tianjin, 7=Hangzhou, 4=Guangzhou, 8=Suzhou} 10 for (int i = 1; i <= 4; i++) { 11 linkedMap.get(i); 12 } 13 System.out.println(linkedMap); // {6=Nanjing, 9=Chengdu, 10=Wuhan, 5=Tianjin, 7=Hangzhou, 8=Suzhou, 1=Beijing, 2=Shanghai, 3=Shenzhen, 4=Guangzhou} 14 } 15 16 private static LinkedHashMap<Integer, String> createMapData() { 17 LinkedHashMap<Integer, String> result = new LinkedHashMap<>(); 18 result.put(3, "Shenzhen"); 19 result.put(6, "Nanjing"); 20 result.put(1, "Beijing"); 21 result.put(9, "Chengdu"); 22 result.put(2, "Shanghai"); 23 result.put(10, "Wuhan"); 24 result.put(5, "Tianjin"); 25 result.put(7, "Hangzhou"); 26 result.put(4, "Guangzhou"); 27 result.put(8, "Suzhou"); 28 return result; 29 } 30 }