侧边栏壁纸
博主头像
Stars-One的杂货小窝博主等级

所有的创作都是有价值的

  • 累计撰写 257 篇文章
  • 累计创建 46 个标签
  • 累计收到 27 条评论

目 录CONTENT

文章目录

Kotlin 集合对象的单条件和多条件排序

Stars-one
2023-06-14 / 0 评论 / 0 点赞 / 361 阅读 / 5380 字

本文不是太难的东西,因为sortedWith之前没怎么用过,所以就记录下

平常开发经常使用到List,Map等数据集合类型,也会经常遇到排序的问题,可以直接使用sortedBysortedByDescending排序

多条件则是使用sortedWith,具体使用用例看见下文

单条件排序

方便起见,我们创建一个类Author,用来保存数据

data class Person(val name:String,val age:Int,val height:Int)
val personList = listOf(
    Person("John", 30, 175),
    Person("Alice", 25, 165),
    Person("Bob", 25, 180),
    Person("John1", 25, 180),
    Person("Alice1", 30, 170)
)

personList.sortedByDescending {
    it.age
}

多条件排序

实际上,kotlin里提供了compareBy方法,方便开发者快速创建一个比较器的对象

val personList = listOf(
    Person("John", 30, 175),
    Person("Alice", 25, 165),
    Person("Bob", 25, 180),
    Person("John", 25, 180),
    Person("Alice", 30, 170)
)

//注意这里使用的是compareBy(即默认为升序,从小到大)
val sortedList = personList.sortedWith(compareBy(
    { it.name }, // 按姓名升序
    { -it.age }, // 按年龄降序(加个符号即代表反序,升序反过来则是降序,从大到小)
    { it.height } // 按身高升序
))

sortedList.forEach { println(it) }

说明

compareBy方法介绍:

compareBy 是 Kotlin 标准库提供的一个函数,它可以帮助我们创建排序条件。该函数接收一个或多个 lambda 表达式,每个 lambda 表示一个排序条件。

compareBy 函数的返回值是一个 Comparator 对象,可以用于对集合中的元素进行排序。使用这个函数的好处是,可以将多个排序条件组合在一起,并且可以方便地扩展排序条件,而不必改变排序算法的实现

之前学Java的时候一直对比较器有些懵逼,不太理解,现在明白了

比较器的返回值为Int,分别为-1,0,1

比如A和B比较:

  • 返回-1,A的顺序要位于B之前
  • 返回0,A的顺序是一致
  • 返回1,A的顺序要位于B之后

Int升序

personList.sortedWith(compareBy(
    { it.age } 
))

//与上面代码等效
personList.sortedBy{
    it.age
}

上面的2段代码都是等效的,解释为按照list里的元素的age进行升序排序,我们需要记住一点,默认排序都是升序的(和sql语句里面是一致的)

Int降序

如果我们想要改为降序,可以变为下面:

personList.sortedWith(compareBy(
    { -it.age } 
))

personList.sortedWith(compareByDescending(
    { it.age } 
))

personList.sortedBy{
    -it.age
}

personList.sortedByDescending{
    it.age
}

注意: sortedBy,compareBy,sortedByDescending,compareByDescending

对于基本类型,如Int,Double,Boolean,String类型,Java已经默认为其实现了比较器接口Comparable接口,所以上面我们能够直接用对象的基本属性来进行排序

如上面的it.age,得到的数值就是一个Int,之后比较器会两两排序,调用Int的比较器接口的对应方法来进行比较

Boolean排序

对于Boolean类型,对于2个对象为Boolean类型的排序,数值true的排在后面

假设我们有这样这样一个需求:

名字包含B字符,优先排在前面

则代码如下:

val personList = listOf(
        Person("John", 30, 175),
        Person("Alice", 25, 165),
        Person("Bob", 25, 180),
        Person("Bab", 25, 180),
        Person("John", 25, 180),
        Person("Alice", 30, 170)
    )

    val sortedList = personList.sortedWith(
        compareBy(
            { it.name.contains("B") }, // 我们把比较器返回的一个Boolean类型
        )
    )

    sortedList.forEach { println(it) }

输出结果:

Person(name=John, age=30, height=175)
Person(name=Alice, age=25, height=165)
Person(name=John, age=25, height=180)
Person(name=Alice, age=30, height=170)
Person(name=Bob, age=25, height=180)
Person(name=Bab, age=25, height=180)

PS:如果想要包含B的排在前面,将条件反转即可,如

val sortedList = personList.sortedWith(
        compareBy(
            { it.name.contains("B").not() }, // 我们把比较器返回的一个Boolean类型
        )
    )

在上面的条件基础上,我们还需要将字符串按字母顺序排序,代码如下:

val sortedList = personList.sortedWith(
        compareBy(
            { it.name.contains("B") }, // 最后排序
            {it.name}
        )
    )

得到下面数据(姓名包含字母B的优先展示,且姓名按照字母升序排序):

Person(name=Bab, age=25, height=180)
Person(name=Bob, age=25, height=180)
Person(name=Alice, age=25, height=165)
Person(name=Alice, age=30, height=170)
Person(name=John, age=30, height=175)
Person(name=John, age=25, height=180)
0

评论区