2016-04-24 6 views
2

Ich benutze eine ConcurrentHashMap in Scala und ich würde gerne die computeIfAbsent()-Methode verwenden, aber kann nicht herausfinden, die Syntax für das zweite Argument. Kann mir jemand zeigen, was die richtige Syntax wäre?Wie benutze ich ConcurrentHashMap computeIfAbsent() in Scala

Wenn Sie den folgenden Code

val data = new ConcurrentHashMap[String, LongAdder] 

data.computeIfAbsent("bob", k: String => new LongAdder()).increment() 

Ich

Type mismatch, expected: Function[_ >: String, _ <: LongAdder], actual: (String) => Any 

Vielen Dank im Voraus

Francis

Antwort

3

Das Problem wird folgende Fehler bekommen ist, dass Sie mit java.util.concurrent.ConcurrentHashMap, die java.util.function.Function als Par akzeptiert Ameter für computeIfAbsent() anstelle von scala.Function1, die Sie daran übergeben.

Da scala keine Lambda-Konvertierung für funktionale Schnittstellen wie Java funktioniert (zumindest nicht ohne die -Xexperimental flag) unterstützen, können Sie dieses Problem lösen, indem eine java.util.function.Function explizit Umsetzung:

val data = new ConcurrentHashMap[String, LongAdder] 
val adderSupplier = new java.util.function.Function[String, LongAdder]() { 
    override def apply(t: String): LongAdder = new LongAdder() 
} 
data.computeIfAbsent("bob", adderSupplier).increment() 

Alternativ, wenn Sie diese brauchen

object FunctionConverter { 
    implicit def scalaFunctionToJava[From, To](function: (From) => To): java.util.function.Function[From, To] = { 
    new java.util.function.Function[From, To] { 
     override def apply(input: From): To = function(input) 
    } 
    } 
} 

import FunctionConverter._ 
val data = new ConcurrentHashMap[String, LongAdder]() 
data.computeIfAbsent("bob", (k: String) => new LongAdder()) // <- implicit conversion applied here 
3

Wenn Sie ermöglichen -Xexperimental Flag Sie scala anonyme Funktion Notation für diese verwenden können: häufiger, können Sie ein Dienstprogramm-Umwandlungsfunktion oder sogar eine implizite Konvertierung schreiben

scala> val data = new java.util.concurrent.ConcurrentHashMap[String, Int] 
data: java.util.concurrent.ConcurrentHashMap[String,Int] = {} 

scala> data.computeIfAbsent("bob", _.size) 
res0: Int = 3 

Beachten Sie, dass Sie noch nicht regelmäßig scala Function

scala> val f: String => Int = _.size 
f: String => Int = <function1> 

scala> data.computeIfAbsent("bob", f) 
<console>:13: error: type mismatch; 
found : String => Int 
required: java.util.function.Function[_ >: String, _ <: Int] 
     data.computeIfAbsent("bob", f) 
          ^

Aber eta-Erweiterung funktioniert passieren kann

scala> def a(s: String): Int = s.size 
a: (s: String)Int 

scala> data.computeIfAbsent("bob", a) 
res3: Int = 3