一、遍歷Map的三種方法
Java中的Map是一種以鍵值對形式存儲數據的容器,常用的實現類有HashMap、LinkedHashMap和TreeMap。遍歷Map是我們在使用Map時最常遇到的問題之一,下面介紹三種常用的遍歷方法。
1. 通過entrySet遍歷
Map map = new HashMap(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for (Map.Entry entry : map.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); }
使用entrySet遍歷時,先獲取到Map的所有entry集合,然後遍歷所有entry,通過entry的getKey和getValue方法獲取鍵值對。
2. 通過keySet遍歷
Map map = new HashMap(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for (Integer key : map.keySet()) { System.out.print(key + " "); System.out.println(map.get(key)); }
使用keySet遍歷時,先獲取到Map的所有key集合,然後遍歷所有key,通過Map的get方法獲取對應的值。
3. 通過values遍歷
Map map = new HashMap(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for (String value : map.values()) { System.out.println(value); }
使用values遍歷時,直接獲取到Map的所有值的集合,然後遍歷所有值。
二、如何遍歷有序Map
有序Map是指像LinkedHashMap和TreeMap這樣的實現類,能夠按照某種順序(通常是插入順序或按照鍵的自然順序)存儲鍵值對。如何遍歷這些有序Map呢?
其實原理和遍歷HashMap一樣,只是在創建實例時需要指定排序的方式。
1. LinkedHashMap
Map map = new LinkedHashMap(16, 0.75f, true); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for (Map.Entry entry : map.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); }
在創建LinkedHashMap時,需要傳入三個參數:initialCapacity(初始化容量)、loadFactor(負載因子)和accessOrder(排序方式)。accessOrder為true時表示按照訪問順序排序,為false時表示按照插入順序排序。
2. TreeMap
Map map = new TreeMap(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for (Map.Entry entry : map.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); }
在創建TreeMap時,只需要像創建普通HashMap一樣傳入默認的初始化容量即可。
三、遍歷Map的性能比較
不同的遍歷方式對Map的性能有影響,下面通過實驗來看看它們之間的性能差異。
實驗代碼如下:
Map map = new HashMap(); Random random = new Random(); for (int i = 0; i < 1000000; i++) { map.put(random.nextInt(1000000), "some value"); } long start = System.currentTimeMillis(); for (Map.Entry entry : map.entrySet()) { // do nothing } long end = System.currentTimeMillis(); System.out.println("遍歷entrySet耗時:" + (end - start) + "ms"); start = System.currentTimeMillis(); for (Integer key : map.keySet()) { // do nothing } end = System.currentTimeMillis(); System.out.println("遍歷keySet耗時:" + (end - start) + "ms"); start = System.currentTimeMillis(); for (String value : map.values()) { // do nothing } end = System.currentTimeMillis(); System.out.println("遍歷values耗時:" + (end - start) + "ms");
實驗結果(遍歷1000000個元素,單位:毫秒):
遍歷entrySet耗時:14ms
遍歷keySet耗時:16ms
遍歷values耗時:33ms
從實驗結果來看,通過entrySet遍歷Map是最快的,而通過values遍歷是最慢的。
四、如何在多線程環境下遍歷Map
在多線程環境下使用Map時,遍歷是一個非常常見的操作,但是需要注意線程安全問題。
如果只是讀取操作,可以直接使用Java 8中的forEach方法,示例代碼如下:
Map map = new ConcurrentHashMap(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.forEach((key, value) -> { System.out.println(key + " " + value); });
如果同時存在讀取和寫入操作,可以使用並發安全的遍歷方式,如下代碼所示:
Map map = new ConcurrentHashMap(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.entrySet().parallelStream().forEach(entry -> { System.out.println(entry.getKey() + " " + entry.getValue()); });
使用parallelStream遍歷Map時,底層會自動實現並發安全,處理速度也會更快。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/151583.html