2016-04-24 270 views
2

我在Scala中使用了ConcurrentHashMap,我想使用computeIfAbsent()方法,但無法弄清楚第二個參數的語法。有人可以告訴我什麼是正確的語法?如何在Scala中使用ConcurrentHashMap computeIfAbsent()

當運行下面的代碼

val data = new ConcurrentHashMap[String, LongAdder] 

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

我收到以下錯誤

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

請多關照

弗朗西斯

回答

3

的問題是,你使用java.util.concurrent.ConcurrentHashMap,它接受java.util.function.Function作爲標準用於computeIfAbsent()而不是scala.Function1,您將其傳遞給它。另外

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() 

,如果你需要這樣的:

在Scala不支持的功能接口拉姆達轉換爲Java那樣(至少不無-Xexperimental flag),你可以通過實現java.util.function.Function明確解決這個更多的時候,你可以寫一個程序轉換功能,甚至是隱式轉換:

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

如果啓用-Xexperimental標誌就可以使用Scala的匿名函數符號此:

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 

請注意,您仍然無法通過常規的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) 
          ^

但ETA-擴大會工作

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

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