общий метод для сортировки списков дочерних элементов запечатанного класса

Я хочу привести свой список к типу класса, который я получаю из аргумента метода.

в основном я хочу заказать свой список на основе поля, которое существует в ClassA. как этого добиться?

sealed class ParentClass
data class ClassA(fieldInClassType: Int) : ParentClass()
data class ClassB(fieldInClassType: Int) : ParentClass()

У меня есть список ClassA и ClassB, и я хочу создать общий метод для их сортировки. в моем старом коде я использовал when(), но это выглядит некрасиво.

поэтому я пытаюсь реорганизовать код в общем методе. Это то, что у меня есть сейчас

private fun <T: ParentClass>foo(data: List<T>,  classType: Class<T>){
    val list = data as classType
    list.sortedBy{it.fieldInClassType}
}

person Remon Shehatta    schedule 24.08.2020    source источник
comment
Где List<Any>? Можете ли вы предоставить дополнительную информацию о том, что вы хотите сделать?   -  person Animesh Sahu    schedule 24.08.2020
comment
@AnimeshSahu обновил вопрос. пожалуйста, проверьте еще раз и дайте мне знать, если вам нужны дополнительные разъяснения.   -  person Remon Shehatta    schedule 24.08.2020
comment
оба ClassA и ClassB являются потомками parentClass, который является запечатанным классом   -  person Remon Shehatta    schedule 24.08.2020


Ответы (1)


Если вы используете запечатанный класс, вы можете использовать when, чтобы убедиться, что ваш код охватывает все потенциальные дочерние классы.

sealed class ParentClass
data class ClassA(val fieldInClassType: Int) : ParentClass()
data class ClassB(val fieldInClassType: Int) : ParentClass()

fun foo(data: List<ParentClass>): List<ParentClass> {
    return data.sortedBy {
        when (it) {
            is ClassA -> it.fieldInClassType
            is ClassB -> it.fieldInClassType
        }
    }
}

fun main() {
    val sorted = foo(listOf(ClassA(4), ClassB(1)))
    sorted.forEach { println(it.javaClass) }
}

Выход:

Класс B

Класс А

Однако....

Если все дочерние классы будут иметь это поле, используйте интерфейс:

interface MyInterface {
    val fieldInClassType: Int
}

sealed class ParentClass : MyInterface
data class ClassA(override val fieldInClassType: Int) : ParentClass()
data class ClassB(override val fieldInClassType: Int) : ParentClass()

fun foo(data: List<ParentClass>): List<ParentClass> {
    return data.sortedBy { it.fieldInClassType }
}
person Clay07g    schedule 24.08.2020
comment
В качестве альтернативы определите абстрактное значение в самом ParentClass, поэтому интерфейс не нужен. sealed class ParentClass { abstract val fieldInClassType: Int } - person Myroslav Kolodii; 19.03.2021