scala中sorted,sortby,sortwith的用法(转)

scala中sorted,sortWith,sortBy用法详解

2017年07月23日 23:07:51 bitcarmanlee 阅读数:9249

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bitcarmanlee/article/details/75949268

scala的集合中提供了三种排序的方式:sorted,sortWith,sortBy。那么这三种方式有什么不同呢?下面我们结合源码来分析一下

1.sorted

先来看看scala中sorted的源码。

  def sorted[B >: A](implicit ord: Ordering[B]): Repr = {
    val len = this.length
    val arr = new ArraySeq[A](len)
    var i = 0
    for (x <- this.seq) {
      arr(i) = x
      i += 1
    }
    java.util.Arrays.sort(arr.array, ord.asInstanceOf[Ordering[Object]])
    val b = newBuilder
    b.sizeHint(len)
    for (x <- arr) b += x
    b.result
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

源码中有两点值得注意的地方: 
1.sorted方法中有个隐式参数ord: Ordering。 
2.sorted方法真正排序的逻辑是调用的java.util.Arrays.sort。

2.sortBy

看看sortBy的源码,很简单。

  def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr = sorted(ord on f)
  • 1

sortBy最后也是调用的sorted方法。不一样的地方在于,sortBy前面还需要提供一个属性。

3.sortWith

sortWith的源码如下。

def sortWith(lt: (A, A) => Boolean): Repr = sorted(Ordering fromLessThan lt)
  • 1

跟前面两个不同的是,sortWith需要传入一个比较函数用来比较!

4.实例

理论部分说完了,下面来干货

object ImplicitValue {

    implicit val KeyOrdering = new Ordering[String] {
        override def compare(x: String, y: String) : Int = {
            y.compareTo(x)
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

首先定义了一个隐式比较器。

    def test1() = {
        import ImplicitValue.KeyOrdering
        val list = List( "a", "g", "F", "B", "c")
        val sortedList = list.sorted
        println(sortedList) // List(g, c, a, F, B)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意因为我们将隐式比较器import了进来,这个时候sorted排序的规则是按照我们自定义的比较器进行比较。在我们自定义的比较器中,定义的是按字符串逆序,所以最终的输出结果为字符串按从大到小的顺序排列!

再来看看sortWith的用法。

    //忽略大小写排序
    def compareIngoreUpperCase(e1: String, e2: String) : Boolean = {
        e1.toLowerCase < e2.toLowerCase
    }

    def test2() = {
        val list = List( "a", "g", "F", "B", "c")
        val sortWithList1 = list.sortWith(_ < _) // List(B, F, a, c, g)
        val sortwithList2 = list.sortWith((left, right) => left < right) //List(B, F, a, c, g)
        val sortwithList3 = list.sortWith(compareIngoreUpperCase) // List(a, B, c, F, g)
        println(sortWithList1)
        println(sortwithList2)
        println(sortwithList3)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

本例中, sortWithList1与sortWithList2最终的结果是一致的,只不过写法不一样而已,都是按字符串从小到大的顺序排列。sortwithList3则是按照传入的compareIngoreUpperCase函数进行排序!

最后看看sortBy的代码

    def test3() = {
        val m = Map(
            -2 -> 5,
            2 -> 6,
            5 -> 9,
            1 -> 2,
            0 -> -16,
            -1 -> -4
        )
        //按key排序
        m.toList.sorted.foreach{
            case (key, value) =>
                println(key + ":" + value)
        }
        println

        //按value排序
        m.toList.sortBy(_._2).foreach {
            case (key, value) =>
                println(key + ":" + value)
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

最后的输出结果为:

-2:5
-1:-4
0:-16
1:2
2:6
5:9

0:-16
-1:-4
1:2
-2:5
2:6
5:9
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值