如何基于 Kotlin 中的公共值字段从两个不同的对象 ArrayList 创建排序的合并列表?

How to create a sorted merged list from two diffrent ArrayList of Objects based on a common value field in Kotlin?

我有两个不同数据的 ArrayLists 类 如下所示:

class Record{
    var id: Long = 0
    var RecordId: Int = 0
    var Record: String? = null
    var title: String? = null
    var description: String? = null
    var longDate: Long = 0
}

class Type{
    var id: Long = 0
    var typeId: Int = 0
    var subTypeId: Int = 0
    var typeString: String? = null
    var longDate: Long = 0
}

var recordsList: ArrayList<Record>
var typesList: ArrayList<Type>

现在,我想要一个这两个的合并列表,它将根据两个对象中的公共字段进行排序,即 longDate。我尝试了.associate , sortedBy, sortedWith(compareBy<>)等,但无法达到预期的效果。

这里还有一点需要注意的是,在比较两个列表的时候,有可能其中一个是空的。

这将生成一个 List<Any>,其中所有项目按 longDate:

排序
(recordsList + typesList)
    .sortedBy { 
        when (it) {
            is Record -> it.longDate
            is Type -> it.longDate
            else -> error("")
        }
    }

或者您可以考虑创建一个具有 val longDate: Long 这两个 类 实现的接口。那么你就不需要 when 表达式,你的 List 就是接口的类型。

像这样的东西应该可以工作,但我个人认为这是代码的味道。无法保证 Record.longDateType.longDate 确实是同一类型(我们知道它是,因为我们创建了模型,但编译器永远不会知道)。

val result = (recordsList + typesList).sortedBy {
        when(it){
            is Record -> it.longDate
            is Type -> it.longDate
            else -> error("incompatible list element $it")
        }
    }

它会像这样工作:(我从模型中删除了一些参数,因为它们在这里并不重要)

    
fun main() {
    
    val recordsList = listOf(Record().apply { longDate = 5 }, Record().apply { longDate = 3})
    val typesList =  listOf(Type().apply { longDate = 3 }, Type().apply { longDate = 2 })
    
    val result = (recordsList + typesList).sortedBy {
        when(it){
            is Record -> it.longDate
            is Type -> it.longDate
            else -> error("incompatible list element $it")
        }
    }
    
    result.forEach{
        println(it.toString())
    }
    
}


class Record{
        var longDate: Long = 0
    override fun toString(): String {
        return "Record(longDate=$longDate)"
    }
}

class Type{
    var longDate: Long = 0
    override fun toString(): String {
        return "Type(longDate=$longDate)"
    }
}

这将输出:

Type(longDate=2)
Record(longDate=3)
Type(longDate=3)
Record(longDate=5)

以更通用的方式进行,这样您就可以在声明每个对象类型要使用的 属性 最有可能使用反射的地方创造乐趣,我会不惜一切代价避免这种情况.

所以我肯定会考虑一个对象是否可以继承另一个对象,或者创建一个接口,或者其他任何东西。

我将以两个问题结束:为什么没有构造函数?为什么是 ArrayList 而不是列表?