2016-04-24 2 views
2

Я использую ConcurrentHashMap в Scala, и я бы хотел использовать метод computeIfAbsent(), но не могу определить синтаксис для второго аргумента. Может ли кто-нибудь показать мне, что будет правильным синтаксисом?Как использовать ConcurrentHashMap computeIfAbsent() в Scala

При выполнении следующего кода

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 в качестве номинала ameter для computeIfAbsent() вместо scala.Function1, который вы передаете ему.

Поскольку Scala не поддерживает преобразование лямбда для функциональных интерфейсов, как Java делает (по крайней мере, не без -Xexperimental flag), вы можете решить эту проблему путем внедрения java.util.function.Function явно:

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

В качестве альтернативы, если вам это нужно чаще, вы можете написать функцию полезности преобразования или даже неявное преобразование:

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 

Обратите внимание, что вы до сих пор не может пройти регулярные 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) 
          ^

Но ета-расширение будет работать

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

scala> data.computeIfAbsent("bob", a) 
res3: Int = 3 
Смежные вопросы