2014-01-30 16 views
1

使用Java,我有一個包含一些項目的Map接口。我想清除其中的所有數據以再次使用它。哪種方法更高效?最有效的清除Java HashMap的方法

params.clear() 

params = new HashMap(); 
+0

http://stackoverflow.com/questions/6757868/map-clear-vs-new-map-which-one-will-be-better – Maroun

+0

'清楚()'將重新使用多個對象(至少1個取決於實施情況)。 clear()運行時和運行HashMap的構造函數的比較方式是依賴於實現的。 我猜'clear()'運行得更快。 –

+1

也許你應該寫一個測試並評估性能? – Saket

回答

3

我寧願clear(),因爲你可以有Map作爲final成員。

class Foo { 
    private final Map<String, String> map = new HashMap<String, String>(); 

    void add(String string) { 
     map.put(string, "a value"); 
    } 

    void clear() { 
     map.clear(); 
    } 
} 

如果你能碰到多線程問題的新Map每次分配。


下面是使用Map包裹在Collections.synchronizedMap幾乎線程的例子,但它每次都分配一個新的地圖,你清楚了。

class MapPrinter { 

    private static Map<String, String> createNewMap() { 
     return Collections.synchronizedMap(new HashMap<String, String>()); 
    } 

    private Map<String, String> map = createNewMap(); 

    void add(String key, String value) { 
     // put is atomic due to synchronizedMap 
     map.put(key, value); 
    } 

    void printKeys() { 
     // to iterate, we need to synchronize on the map 
     synchronized (map) { 
      for (String key : map.values()) { 
       System.out.println("Key:" + key); 
      } 
     } 
    } 

    void clear() { 
     // hmmm.. this does not look right 
     synchronized(map) { 
      map = createNewMap(); 
     } 
    } 
} 

clear方法是負責一個大問題:synchonized(map)將不再如預期,因爲map物體都可改變工作,現在兩個線程可以simultanously是那些​​塊內,因爲它們不鎖定同一目標。爲了實現線程安全,我們必須完全同步外部(並且.synchronizedMap將毫無用處),或者我們可以簡單地使其成爲final並使用Map.clear()

void clear() { 
    // atomic via synchronizedMap 
    map.clear(); 
} 

一個final Map(或任何final

  • 沒有額外的邏輯的其他優點檢查null或創建一個新的。代碼中可能需要編寫的用於更改地圖的開銷可能非常大。
  • 沒有遺忘的意外分配一個Map
  • 「有效的Java#13:回禮不變性」 - 而地圖是可變的,我們引用不是。
+2

你在說什麼類型的問題?我看不出在這方面比創建一個新的「Map」更好。 – Keppil

+1

任何線程都可以保證看到一個'final'變量。所有非final事件都可能需要'volatile'或其他同步方法。如果你創建一個新的地圖,'synchronized(map)'也會失敗,因爲線程可能會在不同的對象上同步。 – zapl

+0

@zapl:您已將地圖定義爲最終地圖,因此,您必須僅清除地圖。而且,這些多線程問題是什麼? –

1

一般: ,如果你不知道如何clear()實現,你不能猜測哪一個會更好的性能。我可以想出合成用例,其中一個或另一個肯定會勝出。 如果您的地圖不包含數以百萬計或數百萬條記錄,您可以採取任何方式。性能將是相同的。

具體來說: HashMap通過清除內部數組的內容來清除。立即使舊地圖內容可用於GC。當你創建一個新的HashMap時,它也會使舊的地圖內容可用於GC + HashMap對象本身。你所交易的幾個CPU週期略少的內存GC

你需要考慮另一個問題:

  • 你通過這個參考一些其他的代碼/組件?您可能需要使用clear(),以便其他代碼可以看到您的更改,反過來也是如此
  • 您是否想要沒有麻煩,沒有副作用的新地圖?我會去創建一個新的。