Map类型介绍与遍历
声明:本文非原创;
在程序员开发过程中,Map有着利用率占比是非常高;很多时间我们只知其用,不知其理;写这个随笔的目的也是希望对伙伴们对Map的理解有一点帮助。
类型介绍
java自带各种Map类。统一可分为三个类型:
1通用Map,用于在应用程序中管理映射,通常在java,util包中实现
HashMap,HashTable,properties,LinkedHashMap,IdentityHashMap,treeMap,weakHashMap,ConcurrentHashMap
2专用Map,通常我们不必建此类Map,而是通过某些其他类进行访问
java.util.jar.Attributes、javax.print.attribute.standard.PrinterStateReasons、java.security.Provider、java.awt.RenderingHints、javax.swing.UIDefaults;
3. 一个用于帮助我们实现自己的Map类的抽象类
AbstractMap
类型区别
HashMap
最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。
TreeMap
能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。
Hashtable
与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
LinkedHashMap
保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
四种常用Map插入与读取性能比较
public class Test { static int hashMapW = 0; static int hashMapR = 0; static int linkMapW = 0; static int linkMapR = 0; static int treeMapW = 0; static int treeMapR = 0; static int hashTableW = 0; static int hashTableR = 0; public static void main(String[] args) { for (int i = 0; i < 10; i++) { Test test = new Test(); test.test(100 * 10000); System.out.println(); } System.out.println("hashMapW = " + hashMapW / 10); System.out.println("hashMapR = " + hashMapR / 10); System.out.println("linkMapW = " + linkMapW / 10); System.out.println("linkMapR = " + linkMapR / 10); System.out.println("treeMapW = " + treeMapW / 10); System.out.println("treeMapR = " + treeMapR / 10); System.out.println("hashTableW = " + hashTableW / 10); System.out.println("hashTableR = " + hashTableR / 10); } public void test(int size) { int index; Random random = new Random(); String[] key = new String[size]; // HashMap 插入 Map<String, String> map = new HashMap<String, String>(); long start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { key[i] = UUID.randomUUID().toString(); map.put(key[i], UUID.randomUUID().toString()); } long end = System.currentTimeMillis(); hashMapW += (end - start); System.out.println("HashMap插入耗时 = " + (end - start) + " ms"); // HashMap 读取 start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { index = random.nextInt(size); map.get(key[index]); } end = System.currentTimeMillis(); hashMapR += (end - start); System.out.println("HashMap读取耗时 = " + (end - start) + " ms"); // LinkedHashMap 插入 map = new LinkedHashMap<String, String>(); start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { key[i] = UUID.randomUUID().toString(); map.put(key[i], UUID.randomUUID().toString()); } end = System.currentTimeMillis(); linkMapW += (end - start); System.out.println("LinkedHashMap插入耗时 = " + (end - start) + " ms"); // LinkedHashMap 读取 start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { index = random.nextInt(size); map.get(key[index]); } end = System.currentTimeMillis(); linkMapR += (end - start); System.out.println("LinkedHashMap读取耗时 = " + (end - start) + " ms"); // TreeMap 插入 key = new String[size]; map = new TreeMap<String, String>(); start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { key[i] = UUID.randomUUID().toString(); map.put(key[i], UUID.randomUUID().toString()); } end = System.currentTimeMillis(); treeMapW += (end - start); System.out.println("TreeMap插入耗时 = " + (end - start) + " ms"); // TreeMap 读取 start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { index = random.nextInt(size); map.get(key[index]); } end = System.currentTimeMillis(); treeMapR += (end - start); System.out.println("TreeMap读取耗时 = " + (end - start) + " ms"); // Hashtable 插入 key = new String[size]; map = new Hashtable<String, String>(); start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { key[i] = UUID.randomUUID().toString(); map.put(key[i], UUID.randomUUID().toString()); } end = System.currentTimeMillis(); hashTableW += (end - start); System.out.println("Hashtable插入耗时 = " + (end - start) + " ms"); // Hashtable 读取 start = System.currentTimeMillis(); for (int i = 0; i < size; i++) { index = random.nextInt(size); map.get(key[index]); } end = System.currentTimeMillis(); hashTableR += (end - start); System.out.println("Hashtable读取耗时 = " + (end - start) + " ms"); } }
Map四种遍历
import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class TestMap { public static void main(String[] args) { Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "a"); map.put(2, "b"); map.put(3, "ab"); map.put(4, "ab"); map.put(4, "ab");// 和上面相同 , 会自己筛选 System.out.println(map.size()); // 第一种: System.out.println("第一种:通过map.keySet()for遍历key和value:"); for (Integer in : map.keySet()) { //map.keySet()返回的是所有key的值 System.out.println(“key=”+in + ";value=" + map.get(in);); } // 第二种: System.out.println("第二种:通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第三种:推荐,尤其是容量大时 System.out.println("第三种:通过Map.entrySet遍历key和value"); for (Map.Entry<Integer, String> entry : map.entrySet()) { //1:几个方法:用上面的名字entry,entry.getKey() ,entry.getValue(),entry.setValue(); //2:map.entrySet() 返回此映射中包含的映射关系的 Set视图 System.out.println("key= " + entry.getKey() + " value= " + entry.getValue()); }// // 第四种: System.out.println("第四种:通过Map.values()遍历所有的value,但不能遍历key"); for (String v : map.values()) { System.out.println("value= " + v); } } }