Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting Kotlin密封类-如何按密封类排序,类似于按枚举排序_Sorting_Kotlin_Enums - Fatal编程技术网

Sorting Kotlin密封类-如何按密封类排序,类似于按枚举排序

Sorting Kotlin密封类-如何按密封类排序,类似于按枚举排序,sorting,kotlin,enums,Sorting,Kotlin,Enums,在Java中,我们可以很容易地按枚举对集合进行排序,如下所示: Collections.sort(toSortEnumList, new Comparator<theEnum>() { @Override public int compare(theEnum o1, theEnum o2) { return o1.ordinal().compareTo(o2.ordinal()); } }); 这张照片是: 美国、德国、中国、巴西 降序排列。

在Java中,我们可以很容易地按枚举对集合进行排序,如下所示:

Collections.sort(toSortEnumList, new Comparator<theEnum>() {
    @Override
    public int compare(theEnum o1, theEnum o2) {
        return o1.ordinal().compareTo(o2.ordinal());
    }
});
这张照片是:

美国、德国、中国、巴西

降序排列。不是我想要的。我想按密封类顺序(如Java枚举中的序号)进行排序,如下所示:

Collections.sort(toSortEnumList, new Comparator<theEnum>() {
    @Override
    public int compare(theEnum o1, theEnum o2) {
        return o1.ordinal().compareTo(o2.ordinal());
    }
});
巴西、美国、德国、中国

我认为密封类应该比枚举更好,但如果我不能做到这一点,可能枚举有优势

更新:多亏罗兰的帮助,我找到了封存的班级名单。但现在我想按它分类:以下是我到目前为止得到的:

Collections.sort(toSortList, object : Comparator<GoodCountries> {
    override fun compare(left: GoodCountries, right: GoodCountries): Int {
        return Integer.compare(
            GoodCountries::class.sealedSubclasses.indexOf(left), 
            GoodCountries::class.sealedSubclasses.indexOf(right)
        )
    }
})
Collections.sort(toSortList,对象:Comparator{
覆盖有趣的比较(左:GoodCountries,右:GoodCountries):Int{
返回整数。比较(
GoodCountries::class.sealedSubclass.indexOf(左),
GoodCountries::class.sealedSubclass.indexOf(右)
)
}
})
但是我在
indexOf
中得到以下错误:

类型推断失败。类型参数T的值应该在输入类型(参数类型、接收器类型或预期类型)中提及。试着明确地指定它


您的问题的快速答案是在比较器中切换
x
y
,即
x::class.java.name.compareTo(y::class.java.name)


较长的答案是,对于您的用例,枚举可能更好。当某些子类看起来与其他子类不同时,密封类会发光,并且拥有多个实例是很有意义的。例如,带有子类
Success
Error
密封类结果
,其中
Success
保存数据而
Error
保存异常。假设您希望对所有国家都一视同仁,您的用例似乎更适合于传统的枚举。

可能不完全符合您的要求,但可能是

虽然密封类似乎没有像您已经注意到的序号一样的东西,但是
类本身(即
GoodCountries::class.sealedsubclass
)上有一个。此外,似乎的顺序是定义的类之一,即此列表中的
巴西
始终排在第一位,
美国
第二位,等等。如果它们不是全部嵌套的,则顺序不同(即,如果一些在外部,则列在第一位)

但是:文档中没有说明此顺序是故意选择的。既不在家也不在家

关于在密封类顺序中对实体进行排序的问题,您可能希望使用以下内容:

val entityList = listOf(Germany(), China(), USA(), Brazil(), Germany())
entityList.sortedBy { // or use sortedWith(compareBy {
  GoodCountries::class.sealedSubclasses.indexOf(it::class)
}.forEach(::println) // or toList...
或者类似于:

GoodCountries::class.sealedSubclasses
    .asSequence()
    .flatMap { klazzInOrder ->
      entityList.asSequence().filter { it::class == klazzInOrder }
    }
    .forEach(::println)
GoodCountries::class.sealedSubclasses.sortedWith(compareBy(nullsLast(String.CASE_INSENSITIVE_ORDER)) { it.simpleName })
  .forEach(::println)
这两种方法可能都不是关于性能的最佳选择,但我想你已经明白了

我之前添加的排序示例(当我没有意识到您实际上想要对实体而不是类型进行排序时):

您甚至可能希望结合使用
nullsLast
CASE\u INSENSITIVE\u ORDER
(如果您没有处理密封类,则最有可能这样做),在这种情况下,您可以编写如下内容:

GoodCountries::class.sealedSubclasses
    .asSequence()
    .flatMap { klazzInOrder ->
      entityList.asSequence().filter { it::class == klazzInOrder }
    }
    .forEach(::println)
GoodCountries::class.sealedSubclasses.sortedWith(compareBy(nullsLast(String.CASE_INSENSITIVE_ORDER)) { it.simpleName })
  .forEach(::println)

您可以给您的
GoodCountries
一个
order
属性,如下所示:

sealed class GoodCountries(val order: Int) {
    class Brazil : GoodCountries(0)
    class USA : GoodCountries(1)
    class Germany : GoodCountries(2)
    class China : GoodCountries(3)
}
这不是一个完美的解决方案,因为您必须手动枚举,但这样可以保证所需的顺序

这样做将大大简化比较代码:

val sorted = toSortList.sortedBy(GoodCountries::order)
println(sorted.map { it::class.simpleName })
输出:

[巴西、美国、德国、中国]


Edit:更新了一个很好的想法,这使得代码更加干净(在
GoodCountries
的构造函数中具有
order
属性,而不是将其作为一个抽象变量,由子类覆盖)。

我想按照枚举的顺序而不是升序对列表进行排序。您建议的比较器如何做到这一点?它正在进行词汇分类。我要道歉。如果不能用密封类,请告诉我哦,我明白了。我不确定是否有任何方法可以在运行时获得该订单。如果您需要,请使用枚举。您能告诉我如何进行排序吗。感谢您的帮助,我找到了以下内容:GoodCountries::class.nestedClasses,但它按错误的顺序提供了类您使用的是哪个版本的Kotlin?由于1.3存在
sealedsubclass
,您应该尝试使用它,而不是
nestedClasses
。。示例实际上在答案中:
GoodCountries::class.sealedsubclass
您可能需要
kotlin reflect
-依赖项
Sealed子类
在“现在可以帮我排序吗?”。我有以下内容,但它说它无法推断类型,indexOf用红色下划线:Collections.sort(toSortList,object:Comparator{override fun compare(left:GoodCountries,right:GoodCountries):Int{return Integer.compare(GoodCountries::class.sealedsubclass.indexOf(left),GoodCountries::class.sealedsubclass.indexOf(right))}})我更新了我的问题,这样你们就可以看到我做了什么far@j2emanue为什么要对
GoodCountries
密封的子类进行排序?如果访问
sealedsubclass
,则顺序是它们的声明*。。。但正如回答中所述,我不知道这是否是故意的。。。所以,把它和一粒盐放在一起。。。我不明白你的示例代码。。。如果您只想按基于字符串的顺序对其排序,您可能只想执行:
GoodCountries::class.sealedsubclass.sortedBy{it.simpleName}
。。。但按照我对你的理解,你想要的是那份声明的顺序。。。答案基本上描述了这一点;-)或者,如果你不喜欢重写,你也可以这样做:(我个人的偏好是避免OOP,因为OOP不会增加任何明显的价值,因为它通常更容易混淆。在我的链接中,我们只是像使用密封特性一样使用密封类。)@Chrispher我只能同意。我更新了我的答案:)