2011-12-26 27 views
1

我有一個如下所示的地圖:Map[ A -> Collection[B]]。這個映射在一個循環中得到更新 - 但是特別的是,更新大多隻是意味着向集合[B](對於某個關鍵字A)添加一個元素B.更新可變HashMap值,這是一個可變集合

我想知道我是否可以通過將列表[]的類型更改爲ListBuffer []來獲得一些加速。

截至目前我的代碼看起來像這樣(簡化):

var incoming = new HashMap[A, List[B]() { 
    override def default(a: A) = List() 
} 
.. 
for(b < someCollectionOfBs){ 
    .. 
    incoming(b.getA) = b :: incoming(b.getA) 
    .. 
} 

這工作得很好。現在,我改變了地圖的類型,所以它看起來是這樣的:

var incoming = new collection.mutable.HashMap[A, ListBuffer[B]() { 
    override def default(a: A) = collection.mutable.ListBuffer() 
} 
.. 
for(b < someCollectionOfBs){ 
    .. 
    incoming(b.getA) += b 
    .. 
} 

注意在B元素是如何加入到集合中的第二個例子(沒有更多的不可變List的變化,因此我們不需要創建並分配新的集合...)。

但是。這不起作用:incoming(X) += ..確實不是更新X的地圖的值,實際上它不會改變任何東西。

我在這裏錯過了什麼?我認爲我應該能夠更新可變HashMap的值...所以,如果我的值是可變集合,爲什麼我不能只添加元素給那些?

回答

6

找不到密鑰時會返回默認值,但不會使用默認值更新地圖。你可以使用getOrElseUpdate

incoming.getOrElseUpdate(b.getA, ListBuffer()) += b 

這應該做你想做的。

附加說明:

如果你關心性能,我不認爲有ListBuffer更換List會買你多少,因爲你前面加上一個List這應該是非常快的。當你想追加到列表時,ListBuffer很方便。你應該看看使用java.util.HashMap,看看是否有幫助。

+0

啊,這是一個邪惡的小動作。 :) 謝謝。 – fgysin 2011-12-27 10:51:44

+0

關於性能:構建列表並不是我擔心的事情,而是實際創建新的List實例。此外,在我的代碼垃圾收集完成率是一個問題,創造更少的對象應該肯定幫助我在那裏... – fgysin 2011-12-27 10:53:51