提问人:RKB 提问时间:2/18/2021 更新时间:2/18/2021 访问量:204
如何根据 Kotlin 中的公共值字段从两个不同的 ArrayList 对象创建排序的合并列表?
How to create a sorted merged list from two diffrent ArrayList of Objects based on a common value field in Kotlin?
问:
我有两个不同 Data 类的 ArrayList,如下所示:
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<>)
在这里,还有一点需要注意的是,在比较两个列表时,其中一个列表可能是空的。
答:
1赞
Tenfour04
2/18/2021
#1
这将产生一个所有项目按以下方式排序:List<Any>
longDate
(recordsList + typesList)
.sortedBy {
when (it) {
is Record -> it.longDate
is Type -> it.longDate
else -> error("")
}
}
或者,您可以考虑创建一个具有这两个类实现的接口。这样你就不需要这个表达式了,你的 List 将是接口的类型。val longDate: Long
when
评论
1赞
Михаил Нафталь
2/18/2021
使用 sortedBy 会更简洁
0赞
RKB
2/18/2021
这很有效,这就是我一直在寻找的东西。我创建了一个界面来避免您建议的那样。(recordsList + typesList)
when
0赞
Tenfour04
2/18/2021
真的,我会让界面包含与将这两者一起呈现在列表中的所有内容。
0赞
Tenfour04
2/18/2021
谢谢,@МихаилНафталь
1赞
AlexT
2/18/2021
#2
这样的东西应该可以工作,但我个人认为这很有代码的味道。不能保证它与类型完全相同(我们知道它是,因为我们创建了模型,但编译器永远不会知道)。Record.longDate
Type.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)
以一种更通用的方式做到这一点,这样你就可以创造一个有趣的方式,你从每个对象类型中说明要使用哪个属性,最有可能使用反射,我会不惜一切代价避免这种情况。
因此,我肯定会考虑一个对象是否可以继承另一个对象,或者创建一个接口,或者其他任何东西。
我将以 2 个问题结束:为什么没有构造函数?为什么是 ArrayList 而不是 list?
评论
Any
Any