generic method to sort lists of sealed class children

Viewed 643

I want to cast my list to the class type that I receive from the method argument.

basically I want to order my list based on a field that exists in the ClassA. how to achieve this?

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

I have a list of ClassA and ClassB and I want to create a generic method to sort them. in my old code, I used when() but it looks ugly.

so I am trying to refactor the code in a generic method. This is what I have now

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

If you are using a sealed class, you can utilize when in order to ensure your code covers all potential children classes.

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) }
}

Output:

ClassB

ClassA

However....

If all the child classes will have that field, use an interface:

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 }
}
Related