android 为什么Kotlin不能按第一个字段降序排列集合,然后按第二个字段升序排列集合

mgdq6dx1  于 2023-06-04  发布在  Android
关注(0)|答案(2)|浏览(458)

我想按nextTime和timePart对任务集合进行降序排序。
排序代码在person集合中工作正常,但是,当它应用于tasks集合时,它并不按timePart降序排序,这真的很奇怪。结果如下所示。

2023-05-30 23:44:56.205 24842-24863/com.maxim.wordcard I/System.out: Person(name='Olivia', age=20)
    2023-05-30 23:44:56.205 24842-24863/com.maxim.wordcard I/System.out: Person(name='Olivia', age=25)
    2023-05-30 23:44:56.205 24842-24863/com.maxim.wordcard I/System.out: Person(name='Harry', age=10)
    2023-05-30 23:44:56.205 24842-24863/com.maxim.wordcard I/System.out: Person(name='Harry', age=15)

    2023-05-30 23:33:07.059 23361-23381/com.maxim.wordcard I/System.out: Task(nextTime='Wed May 31 23:23:07 GMT+08:00 2023', time=1130)
    2023-05-30 23:33:07.060 23361-23381/com.maxim.wordcard I/System.out: Task(nextTime='Wed May 31 23:13:07 GMT+08:00 2023', time=1120)
    2023-05-30 23:33:07.060 23361-23381/com.maxim.wordcard I/System.out: Task(nextTime='Tue May 30 23:33:07 GMT+08:00 2023', time=1140)
    2023-05-30 23:33:07.060 23361-23381/com.maxim.wordcard I/System.out: Task(nextTime='Tue May 30 23:23:07 GMT+08:00 2023', time=1130).   



package com.maxim.wordcard

import com.maxim.wordcard.database.entity.Task
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import java.util.*

@RunWith(JUnit4::class)
class CollectionSort {

    @Test
    fun testSortCollection() {
        val calendar = Calendar.getInstance()
        val task1 = Task(calendar.time, 1, 1)
        task1.timePart = calendar.get(Calendar.HOUR) * 100 + calendar.get(Calendar.MINUTE) + calendar.get(Calendar.SECOND)
        calendar.add(Calendar.MINUTE, -10)
        val task2 = Task(calendar.time, 1, 1)
        task2.timePart = calendar.get(Calendar.HOUR) * 100 + calendar.get(Calendar.MINUTE) + calendar.get(Calendar.SECOND)
        calendar.add(Calendar.DATE, 1)
        val task3 = Task(calendar.time, 1, 1)
        task3.timePart = calendar.get(Calendar.HOUR) * 100 + calendar.get(Calendar.MINUTE) + calendar.get(Calendar.SECOND)
        calendar.add(Calendar.MINUTE, -10)
        val task4 = Task(calendar.time, 1, 1)
        task4.timePart = calendar.get(Calendar.HOUR) * 100 + calendar.get(Calendar.MINUTE) + calendar.get(Calendar.SECOND)
        val tasks = arrayListOf<Task>(task1, task2, task3, task4)
        tasks.sortWith(compareByDescending<Task> { it.nextTime }.thenBy { it.timePart })
        for (task in tasks) {
            println(task)
        }
    }

    @Test
    fun testPerson() {
        val persons = mutableListOf(
            Person("Olivia", 25),
            Person("Harry", 15),
            Person("Olivia", 20),
            Person("Harry", 10)
        )
        persons.sortWith(compareByDescending<Person>{ it.name }.thenBy { it.age })
        for (person in persons) {
            println(person)
        }
    }

    class Person(val name: String, val age: Int, val test: String?) {

        constructor(name: String, age: Int): this(name, age, "hell")
        override fun toString(): String {
            return "Person(name='$name', age=$age)"
        }
    }
}
    
 

       package com.maxim.wordcard.database.entity
        
        import androidx.room.ColumnInfo
        import androidx.room.Entity
        import androidx.room.Ignore
        import androidx.room.PrimaryKey
        import java.sql.Time
        import java.util.*
        
        @Entity
        data class Task(
            @PrimaryKey(autoGenerate = true) var id: Int?,
            @ColumnInfo var unknown: Int,
            @ColumnInfo var search: Int,
            @ColumnInfo var know: Int,
            @ColumnInfo var startTime: Date,
            @ColumnInfo var nextTime: Date,
        
            /**
             * [TaskStatus]
             */
            @ColumnInfo var status: Int?,
            @ColumnInfo var wordId: Long?,
            @ColumnInfo var courseId: Long?,
            @Ignore var isSkim: Boolean = false,
            @Ignore var isShowDefinition: Boolean = false,
            @Ignore var timePart: Int? = null,
        ) {
            constructor(wordId: Long?, courseId: Long?) : this(null, 0, 0, 0, Date(), Date(), TaskStatus.UNSTART.status, wordId, courseId)
        
            @Ignore
            constructor(nextTime: Date, wordId: Long?, courseId: Long?) : this(null, 0, 0, 0, Date(), nextTime, TaskStatus.UNSTART.status, wordId, courseId)
            /**
             * Task is used as a key, its hashcode should keep the same, hence, exclude some fields which
             * may change due to user interaction.
             */
            override fun hashCode(): Int {
                return id.hashCode() + wordId.hashCode() + startTime.hashCode()
            }
        
            override fun equals(other: Any?): Boolean {
                if (this === other) return true
                if (other !is Task) return false
                return id == other.id && wordId == other.wordId && startTime == other.startTime
            }
        
        //    override fun compareTo(other: Task): Int {
        //        return compareValuesBy(this, other, { it.nextTime }, { it.timePart })
        //    }
        
            override fun toString(): String {
                return "Task(nextTime='$nextTime', time=$timePart)"
            }
        
        
        }
jxct1oxe

jxct1oxe1#

这是因为thenBy将按升序排序。您可以通过使用thenByDescending来解决这个问题。像这样:

persons.sortWith(compareByDescending<Person>{ it.name }.thenByDescending { it.age })
8xiog9wr

8xiog9wr2#

选择日期部分,然后选择要排序的时间部分。第二个排序操作将仅在两个元素在第一个排序操作中相等时执行。问题中的代码出现故障,因为它们在第一次排序操作时不相等。我分享的最终功能代码如下。

private var dateFormat = SimpleDateFormat("yyyy-MM-dd")
private var timeFormat = SimpleDateFormat("HH:mm:ss")

fun updateData(data: MutableMap<Task, Word>) {
    this.data.clear()
    val sortedByDescending = data.keys.sortedWith(
        compareByDescending<Task> { selectDate(it) }.thenBy { selectTime(it) })
    this.data.addAll(sortedByDescending)

    notifyDataSetChanged()
}

private fun selectDate(task: Task): String {
    val result = dateFormat.format(task.nextTime.time)
    return result
}

private fun selectTime(task: Task): String {
    val result = timeFormat.format(task.nextTime.time)
    return result
}

相关问题