首页 > 解决方案 > 如何使用 java.lang.reflect.Type 在 Scala 中动态(运行时)生成排序集合?

问题描述

给定一组项目,我需要在 Scala 中为 a 生成排序集合,java.lang.reflect.Type但我无法这样做。以下片段可能会更好地解释。

  def buildList(paramType: Type): SortedSet[_] = {
    val collection = new Array[Any](5)
    for (i <- 0 until 5) {
      collection(i) = new EasyRandom().nextObject(paramType.asInstanceOf[Class[Any]])
    }
    SortedSet(collection:_*)
  }

我无法执行此操作,因为我收到错误“没有为参数 ord 找到隐含:Ordering[Any]”。如果我换成未排序的类型,例如Set.

  def buildList(paramType: Type): Set[_] = {
    val collection = new Array[Any](5)
    for (i <- 0 until 5) {
      collection(i) = new EasyRandom().nextObject(paramType.asInstanceOf[Class[Any]])
    }
    Set(collection:_*)
  }

如何在运行时动态构建排序集?我一直在研究杰克逊如何尝试实现同样的目标,但我不太明白如何到达T这里:https ://github.com/FasterXML/jackson-module-scala/blob/0e926622ea4e8cef16dd757fa85400a0b9dcd1d3/src/main/scala /com/fasterxml/jackson/module/scala/introspect/OrderingLocator.scala#L21

(如果我的问题不清楚,请原谅。)

标签: scala

解决方案


发生这种情况是因为SortedSet需要给定类型的上下文(隐式)Ordering类型类实例A

但是,正如 Luis 在评论部分所说,我强烈建议您不要使用这种方法,而是使用更安全、强类型的方法。

在一些库(如magnolia)的帮助下,生成随机案例类(我想您正在使用它,因为您使用的是 Scala)应该很容易。这会将您的代码变成如下所示:

def randomList[A : Ordering : Arbitrary]: SortedSet[A] = {
  val arb: Arbitrary[A] = implicitly[Arbitrary[A]]
  val sampleData = (1 to 5).map(arb.arbitrary.sample)

  SortedSet(sampleData)
}

这种方法涉及一些重要的概念,如隐式和类型类,但更安全。


推荐阅读