【问题标题】:Scala Map and ConcurrentHashMap throw a java.lang.UnsupportedOperationExceptionScala Map 和 ConcurrentHashMap 抛出 java.lang.UnsupportedOperationException
【发布时间】:2016-11-28 20:18:24
【问题描述】:

有了这个简单的代码

import scala.collection.JavaConversions._
new java.util.concurrent.ConcurrentHashMap[String,String]  ().toMap.put("abc","def")

Scala 抛出 java.lang.UnsupportedOperationException。

为什么?

【问题讨论】:

  • toMap 是做什么的? ConcurrentHashMap 已经是一个映射。我想,new java.util.concurrent.ConcurrentHashMap[String,String] ().put("abc","def") 应该可以正常工作。

标签: java multithreading scala containers java.util.concurrent


【解决方案1】:

这就是发生的事情(我认为):

  1. 您使用new java.util.concurrent.ConcurrentHashMap[String,String]() 创建并发Java 哈希映射
  2. 然后使用toMap 将其转换为不可变的scala Map
  3. 由于toMap 未在java.util.concurrent.ConcurrentHashMap 上定义,因此应用到可变 scala 映射的隐式转换。然后toMap 将这个可变 Map 变成一个不可变 Map
  4. 然后调用 scala.collection.immutable.Map 上未定义的“put(...)”。
  5. 然而,scala 编译器很方便地在您的导入 import scala.collection.JavaConversions._ 中找到了从 scala.collection.immutable.Mapjava.util.Map 的转换,其中定义了 put(...) 方法。但是,转换会返回一个扩展 AbstractMap 的包装器。
  6. 但是在该包装器中没有实现put(...) 方法。因此,调用以java.util.AbstractMap 的默认实现结束,它并没有真正实现put(...),而是抛出UnsupportedOperationException

我想由此引起的混乱,是现在大多数 scala 开发人员更喜欢 import scala.collection.JavaConverters._ 而不是 import scala.collection.JavaConversions._ 的原因之一。

所以,我认为,这可能是您想要做的:

import scala.collection.JavaConverters._
new java.util.concurrent.ConcurrentHashMap[String,String]().asScala.put("abc","def")    

【讨论】:

  • 只是一个很小的变化:最后一次转换是从scala.collection.Mapjava.util.Map。但它实际上返回了一个扩展AbstractMap 的包装器,它将get 之类的方法委托给相应的scala.collection.Map 方法。而且put没有对应的方法,所以没有被覆盖,继承AbstractMap的实现。
  • @AlexeyRomanov 谢谢,那里有点懒惰。我编辑了我的答案,希望现在更准确。
【解决方案2】:

与 Java 不同,Scala 中的默认集合是不可变的。如果您查看Map 的api(找到here),您会发现Map 缺少方法put。所以这个例外非常正确地告诉你,Map 不能做你想让它做的事情。如果你想用值填充Map

Map("abc" -> "def")

顺便说一句,不可变集合已经是线程安全的。无需使用ConcurrentHashMap

【讨论】:

  • Re,“顺便说一句……不需要使用 ConcurrentHashMap。”见stackoverflow.com/questions/6692008/…
  • @jameslarge 他们的性能几乎等于从 Java7 开始,这在您所指问题的答案中直接解释。还是你的意思是别的?
  • 此外,对 scala 的不可变映射的性能进行了额外优化:benchmarksrc。视实际需求而定
猜你喜欢
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-20
  • 2012-12-09
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多