2014-05-09 4 views
2

j'écrire du code souvent moi-même comme ceci:putIfAbsent pour les cartes immuables?

import scala.collection.immutable._ 

var foos = Map.empty[Int, Foo] 

def fooOf(n: Int): Foo = { 
    foos.get(n) match { 
    case Some(foo) => foo 
    case None => 
     val foo = new Foo(n) 
     foos = foos.updated(n, foo) 
     foo 
    } 
} 

Avec une carte concurrente, le code ressemble beaucoup plus agréable:

import scala.collection.concurrent._ 

var foos = TrieMap.empty[Int, Foo] 

def fooOf(n: Int): Foo = { 
    val foo = new Foo(n) 
    foos.putIfAbsent(n, foo) getOrElse foo 
} 

Mais je veux vraiment une carte non-simultanée, immuable. Y at-il quelque chose comme putIfAbsent pour cela?

(Soit dit en passant, dans l'exemple en même temps, est-il possible de créer le Foo que si elle est en effet absent?)

Répondre

2

Si vous êtes d'accord avec une variable mutable (et semble que vous êtes comme vous utilisé var foos dans les deux exemples et seulement une collection spécifiée immuable) ce qui devrait correspondre à vos besoins:

var foos = Map.empty[Int, Foo] 

def fooOf(n: Int): Foo = { 
    foos.getOrElse(n, { 
    foos = foos.updated(n, new Foo(n)) 
    foos(n) 
    }) 
} 
+0

Vous pouvez faire foos.getOrElse (n, {/ * pas trouvé, faire quelque chose d'autre * /}) avec un seul appel . – DCKing

+0

Merci @DCKing - juste une réponse éditée pour utiliser le getOrElse de la carte – Exupery

+0

Ce n'est pas une bonne idée, il a un effet secondaire et ne fonctionne pas avec la concurrence. –