将java.util.IdentityHashMap转换为scala.immutable.Map
将将java.util.IdentityHashMap转换为scala.immutable.Map,scala,collections,immutability,Scala,Collections,Immutability,将java.util.IdentityHashMap[a,B]转换为scala.immutable.Map[a,B]的子类型的最简单方法是什么?我需要将钥匙分开,除非它们是eq 以下是我迄今为止所尝试的: scala> case class Example() scala> val m = new java.util.IdentityHashMap[Example, String]() scala> m.put(Example(), "first!") scala> m.
java.util.IdentityHashMap[a,B]
转换为scala.immutable.Map[a,B]
的子类型的最简单方法是什么?我需要将钥匙分开,除非它们是eq
以下是我迄今为止所尝试的:
scala> case class Example()
scala> val m = new java.util.IdentityHashMap[Example, String]()
scala> m.put(Example(), "first!")
scala> m.put(Example(), "second!")
scala> m.asScala // got a mutable Scala equivalent OK
res14: scala.collection.mutable.Map[Example,String] = Map(Example() -> first!, Example() -> second!)
scala> m.asScala.toMap // doesn't work, since toMap() removes duplicate keys (testing with ==)
res15: scala.collection.immutable.Map[Example,String] = Map(Example() -> second!)
处理这个问题的一种方法是改变平等对类的意义,例如
scala> case class Example() {
override def equals( that:Any ) = that match {
case that:AnyRef => this eq that
case _ => false
}
}
defined class Example
scala> val m = new java.util.IdentityHashMap[Example, String]()
m: java.util.IdentityHashMap[Example,String] = {}
scala> m.put(Example(), "first!")
res1: String = null
scala> m.put(Example(), "second!")
res2: String = null
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> m.asScala
res3: scala.collection.mutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
scala> m.asScala.toMap
res4: scala.collection.immutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
或者,如果不想更改类的相等性,可以制作一个包装器
当然,它的性能不如使用
eq
而不是=
的映射;也许值得一提……处理这个问题的一种方法是改变平等对类的意义,例如
scala> case class Example() {
override def equals( that:Any ) = that match {
case that:AnyRef => this eq that
case _ => false
}
}
defined class Example
scala> val m = new java.util.IdentityHashMap[Example, String]()
m: java.util.IdentityHashMap[Example,String] = {}
scala> m.put(Example(), "first!")
res1: String = null
scala> m.put(Example(), "second!")
res2: String = null
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> m.asScala
res3: scala.collection.mutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
scala> m.asScala.toMap
res4: scala.collection.immutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
或者,如果不想更改类的相等性,可以制作一个包装器
当然,它的性能不如使用
eq
而不是=
的映射;也许值得一提……处理这个问题的一种方法是改变平等对类的意义,例如
scala> case class Example() {
override def equals( that:Any ) = that match {
case that:AnyRef => this eq that
case _ => false
}
}
defined class Example
scala> val m = new java.util.IdentityHashMap[Example, String]()
m: java.util.IdentityHashMap[Example,String] = {}
scala> m.put(Example(), "first!")
res1: String = null
scala> m.put(Example(), "second!")
res2: String = null
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> m.asScala
res3: scala.collection.mutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
scala> m.asScala.toMap
res4: scala.collection.immutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
或者,如果不想更改类的相等性,可以制作一个包装器
当然,它的性能不如使用
eq
而不是=
的映射;也许值得一提……处理这个问题的一种方法是改变平等对类的意义,例如
scala> case class Example() {
override def equals( that:Any ) = that match {
case that:AnyRef => this eq that
case _ => false
}
}
defined class Example
scala> val m = new java.util.IdentityHashMap[Example, String]()
m: java.util.IdentityHashMap[Example,String] = {}
scala> m.put(Example(), "first!")
res1: String = null
scala> m.put(Example(), "second!")
res2: String = null
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> m.asScala
res3: scala.collection.mutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
scala> m.asScala.toMap
res4: scala.collection.immutable.Map[Example,String] = Map(Example() -> second!, Example() -> first!)
或者,如果不想更改类的相等性,可以制作一个包装器
当然,它的性能不如使用
eq
而不是=
的映射;也许值得一提……这是一个在Scala中实现身份映射的简单方法。在使用上,它应该类似于标准的不可变映射
用法示例:
val im = IdentityMap(
new String("stuff") -> 5,
new String("stuff") -> 10)
println(im) // IdentityMap(stuff -> 5, stuff -> 10)
你的情况:
import scala.collection.JavaConverters._
import java.{util => ju}
val javaIdentityMap: ju.IdentityHashMap = ???
val scalaIdentityMap = IdentityMap.empty[String,Int] ++ javaIdentityMap.asScala
实现本身(出于性能原因,可能还有一些方法需要重写):
下面是Scala中身份映射的一个简单实现。在使用上,它应该类似于标准的不可变映射 用法示例:
val im = IdentityMap(
new String("stuff") -> 5,
new String("stuff") -> 10)
println(im) // IdentityMap(stuff -> 5, stuff -> 10)
你的情况:
import scala.collection.JavaConverters._
import java.{util => ju}
val javaIdentityMap: ju.IdentityHashMap = ???
val scalaIdentityMap = IdentityMap.empty[String,Int] ++ javaIdentityMap.asScala
实现本身(出于性能原因,可能还有一些方法需要重写):
下面是Scala中身份映射的一个简单实现。在使用上,它应该类似于标准的不可变映射 用法示例:
val im = IdentityMap(
new String("stuff") -> 5,
new String("stuff") -> 10)
println(im) // IdentityMap(stuff -> 5, stuff -> 10)
你的情况:
import scala.collection.JavaConverters._
import java.{util => ju}
val javaIdentityMap: ju.IdentityHashMap = ???
val scalaIdentityMap = IdentityMap.empty[String,Int] ++ javaIdentityMap.asScala
实现本身(出于性能原因,可能还有一些方法需要重写):
下面是Scala中身份映射的一个简单实现。在使用上,它应该类似于标准的不可变映射 用法示例:
val im = IdentityMap(
new String("stuff") -> 5,
new String("stuff") -> 10)
println(im) // IdentityMap(stuff -> 5, stuff -> 10)
你的情况:
import scala.collection.JavaConverters._
import java.{util => ju}
val javaIdentityMap: ju.IdentityHashMap = ???
val scalaIdentityMap = IdentityMap.empty[String,Int] ++ javaIdentityMap.asScala
实现本身(出于性能原因,可能还有一些方法需要重写):
在这种情况下,最好通过实现
Eq
typeclass的实例来对等式的概念进行建模。更改类(尤其是case类)的相等语义是非常危险的。在这种情况下,相等的概念最好通过实现Eq
typeclass的实例来建模。更改类(尤其是case类)的相等语义是非常危险的。在这种情况下,相等的概念最好通过实现Eq
typeclass的实例来建模。更改类(尤其是case类)的相等语义是非常危险的。在这种情况下,相等的概念最好通过实现Eq
typeclass的实例来建模。更改类(尤其是case类)的相等语义是非常危险的。