【问题标题】:Is this the correct way to sort generic type?这是对泛型类型进行排序的正确方法吗?
【发布时间】:2022-08-19 01:55:52
【问题描述】:

我只是想写一个使用泛型的冒泡排序代码。我不确定这是否是为泛型编写排序逻辑的正确方法。这里 \"if\" 条件给出编译时错误.对于任何特定类型,这都可以正常工作。我该如何解决这个问题并以更好的方式对其进行编程?提前致谢。

def sortAny[T](list: Array[T]): Array[T] = {
var count = 0
while (count < list.length) {
  for (count <- 0 until list.length - 1) {
    if (list(count) > list(count + 1)) {
      val temp = list(count)
      list(count) = list(count + 1)
      list(count + 1) = temp
    }
  }
  count = count + 1
}

list

}

    标签: scala generics


    【解决方案1】:
    def sortAny[T <% Ordered[T]](list: Array[T]): Array[T] = {
    var count = 0
    while (count < list.length) {
      for (count <- 0 until list.length - 1) {
        if (list(count) > list(count + 1)) {
          val temp = list(count)
          list(count) = list(count + 1)
          list(count + 1) = temp
        }
      }
      count = count + 1
      }
    
    list
    }
    

    输出将是

    sortAny: [T](list: Array[T])(implicit evidence$1: T => Ordered[T])Array[T]
    

    T <% S(视图绑定)表示类型 T 必须可转换为 S,因此它必须是 S 的子类型或已定义隐式转换。

    【讨论】:

    • 视图边界已被弃用。您可以使用上下文边界将其修改为答案吗?
    • 为我工作。我仍然不清楚这一步实际上在做什么“T <% Ordered[T]”。感谢@ADK的回答
    • 该步骤是插入从类型 T 到类型 Ordered[T] 的隐式转换,仅当类型 T 不是 Ordered[T] 的子类型时。所以类型 T 变成了 Ordered[T] 类型的“可见”。这是必要的,以便您可以比较和排序通用变量。换句话说,它使您的泛型类型具有可比性。
    • 知道了。感谢这个简单明了的解释@AlinGabrielArhip
    【解决方案2】:

    添加一个上下文绑定回答完整性。为了使用它,需要一个类型类代替类型转换,它有一个比较方法,它采用T 类型的 2 个元素。 Ordered trait 在这里不适合作为类型类,因为它的比较方法只需要 T 类型的 1 个元素。

    Ordered 旨在混合并比较 this 实例与提供的元素 T。解决方案当然是改用 Ordering 特征:

      def sortAny[T: Ordering](list: Array[T]): Array[T] = {
        var count = 0
        while (count < list.length) {
          for (count <- 0 until list.length - 1) {
            if (implicitly[Ordering[T]].gt(list(count), list(count + 1))) {
              val temp = list(count)
              list(count) = list(count + 1)
              list(count + 1) = temp
            }
          }
          count = count + 1
        }
    
        list
      }
    

    这对内置类型都有效,因为 Scala 为它们提供了隐式排序:

      sortAny(Array(4, 2, 5, 7, 32, 1213, 32))            // Array(2, 4, 5, 7, 32, 32, 1213)
      sortAny(Array("John", "Helen", "Merry", "Chris"))   // Array(Chris, Helen, John, Merry)
    

    对于自定义类型也是如此,但是您必须提供隐式 Ordering - 或 - 在自定义类型中混合 Ordered 特征。后者之所以有效,是因为:

    Ordered 和 Ordering 都提供了允许使用它们的隐式 可以互换。

    所以Scala会自动为你的自定义类型创建一个隐式的Ordering,只要你的自定义类型混合在Ordered中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      相关资源
      最近更新 更多