代码之家  ›  专栏  ›  技术社区  ›  David

Java SortedMap到Scala树映射

  •  3
  • David  · 技术社区  · 16 年前

    奇怪的是,有些背景是序列化结构是通过XStream编写的,在取消序列化时,我注册了一个转换器,它可以表示任何可以分配给它的内容 SortedMap[Comparable[_],_] Object 我可以安全地投下,因为我知道它是 SortedMap[可比[u],u]

    // a conversion from comparable to ordering
    scala> implicit def comparable2ordering[A <: Comparable[A]](x: A): Ordering[A] = new Ordering[A] {
         |     def compare(x: A, y: A) = x.compareTo(y)
         |   }
    comparable2ordering: [A <: java.lang.Comparable[A]](x: A)Ordering[A]
    
    // jm is how I see the map in the converter. Just as an object. I know the key
    // is of type Comparable[_]
    scala> val jm : Object = new java.util.TreeMap[Comparable[_], String]()        
    jm: java.lang.Object = {}
    
    // It's safe to cast as the converter only gets called for SortedMap[Comparable[_],_]
    scala> val b = jm.asInstanceOf[java.util.SortedMap[Comparable[_],_]]
    b: java.util.SortedMap[java.lang.Comparable[_], _] = {}
    
    // Now I want to convert this to a tree map
    scala> collection.immutable.TreeMap() ++ (for(k <- b.keySet) yield { (k, b.get(k))  })
    <console>:15: error: diverging implicit expansion for type Ordering[A]
    starting with method Tuple9 in object Ordering
           collection.immutable.TreeMap() ++ (for(k <- b.keySet) yield { (k, b.get(k))  })
    
    2 回复  |  直到 16 年前
        1
  •  2
  •   retronym    16 年前

    // The type inferencer can't guess what you mean, you need to provide type arguments.
    // new collection.immutable.TreeMap  
    // <console>:8: error: diverging implicit expansion for type Ordering[A]
    //starting with method Tuple9 in object Ordering
    //       new collection.immutable.TreeMap
    //       ^
    

    你可以写一个隐式的 Comparable[T] 作为 Ordering[T] 具体如下。

    // This implicit only needs the type parameter.
    implicit def comparable2ordering[A <: Comparable[A]]: Ordering[A] = new Ordering[A] {
       def compare(x: A, y: A) = x.compareTo(y)
    }
    
    trait T extends Comparable[T]
    
    implicitly[Ordering[T]]
    

    但是,如果您真的不知道密钥的类型,我认为您无法创建 Ordering Comparable#compareTo ,至少没有反省:

    val comparableOrdering = new Ordering[AnyRef] {
      def compare(a: AnyRef, b: AnyRef) = {
        val m = classOf[Comparable[_]].getMethod("compareTo", classOf[Object])
        m.invoke(a, b).asInstanceOf[Int]
      }
    }
    new collection.immutable.TreeMap[AnyRef, AnyRef]()(comparableOrdering)
    
        2
  •  0
  •   Dr. Hans-Peter Störr    13 年前

    collection.immutable.TreeMap[whatever,whatever]() ++ ...
    

    (对不起,我没有时间检查这一点对问题中发布的消息来源的适用性。)