2

我想用番石榴 Range。但是,它希望元素实现Comparable接口。所以我不能简单地使用

val range = Range.open(4, 5)

因为Int没有实现Comparableor Ordered。但是有一个Ordering[Int]类型类。到目前为止我唯一的想法是使用视图边界

def open[T](from:T, to:T)(implicit ord: T => Ordered[T]) = Range.open(ord(from), ord(to))

但我得到了一个 CCE:

 val range = open(4,5)                           //> java.lang.ClassCastException: scala.runtime.RichInt cannot be cast to java.l
                                                  //| ang.Integer
                                                  //|   at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:106)
                                                  //|   at scala.math.Ordering$Int$.compare(Ordering.scala:256)
                                                  //|   at scala.runtime.OrderedProxy$class.compare(ScalaNumberProxy.scala:71)
                                                  //|   at scala.runtime.RichInt.compare(RichInt.scala:15)
                                                  //|   at scala.math.Ordered$class.compareTo(Ordered.scala:91)
                                                  //|   at scala.runtime.RichInt.compareTo(RichInt.scala:15)
                                                  //|   at com.google.common.collect.Range.compareOrThrow(Range.java:711)
                                                  //|   at com.google.common.collect.Cut.compareTo(Cut.java:75)
                                                  //|   at com.google.common.collect.Range.<init>(Range.java:364)
                                                  //|   at com.google.common.collect.Range.create(Range.java:156)
                                                  //|   at com.google.common.collect.Range.open(Range.java:168)

为什么这会导致 ClassCastException?

有一个更好的方法吗?注意: usingInt只是一个最小的例子。我有更复杂的类型,它们没有实现OrderedOrdering在范围内。

4

2 回答 2

4

只需明确指定要装箱到 a java.lang.Integer

import java.lang.{Integer => jI}
Range.open[jI](3,5)

如果您不喜欢在每次通话时都这样做,请按照您的建议包装通话。

于 2013-08-06T20:37:22.037 回答
2

你得到一个 CCE 因为RichInt没有实现Ordered[RichInt]但是Ordered[Int].

我建议你自己包装它,类似于

case class AsOrdered[T](val value: T)(implicit ord: Ordering[T]) extends Ordered[AsOrdered[T]] {
  override def compare(that: AsOrdered[T]) = ord.compare(value, that.value)
}

def open[T: Ordering](from: T, to: T) = {
  val ord = implicitly[Ordering[T]]
  Range.open(AsOrdered(from), AsOrdered(to))
} 

您需要提供额外的逻辑来提取值,因为您不会得到 aRange[Int]而是 aRange[AsOrdered[Int]]

编辑:

我们刚刚发布了一个包含Range / RangeSet的Mango版本,该版本包装了 Guava 实现,采用.Ordering

于 2013-08-09T05:19:05.013 回答