使用Kotlin中的函数式编程处理具有相同代码的两种不同类型的列表

时间:2018-10-02 06:54:43

标签: kotlin functional-programming

我有两个类型不同的列表list1和list2。我有一个方法,对列表执行相同的操作。

我正在使用lambdas,如果我使用的是Any类型的List,则无法以(it.prop1)的身份访问该属性。

有什么解决方案可以避免lambda出现此问题吗?

val list1: List<Student> = ..
val list2: List<Teacher> = ..

list1.filter {
    school.contains(it.prop1) }
.forEach {
    total +=  it.prop2.toLong()
}

list2.filter {
    school.contains(it.prop1) }
.forEach {
    total +=  it.prop2.toLong()
}

谢谢。

3 个答案:

答案 0 :(得分:0)

据我所知你做不到。您可以利用通用接口。

例如:

interface Human{
    val age: Int
}

class Student(override val age: Int): Human

class Teacher(override val age: Int, val salary: Double):Human

fun x(){
    val list1: List<Student> = ...
    val list2: List<Teacher> = ...
    val school: List<Human> = ...

    val result = school
        .filter { it is Student }
        .sumBy { it.age}

    val result2 = school
        .filter { it is Teacher }
        .sumBy { it.age }

}

答案 1 :(得分:0)

您可以使用Type Checks and Casts

class Student(val prop1:Int, val prop2:Int)
class Teacher(val prop1:Int, val prop2:Int)
val list : List<Any> = listOf(Student(1,1),Student(2,2),Student(3,3),Teacher(1,1),Teacher(2,2),Teacher(3,3))
var total : Long = 0
val school : Array<Int> = arrayOf(1,2)
list.filter{
    if(it is Student)
    {
        school.contains((it as Student).prop1)
    }
    else if(it is Teacher)
    {
        school.contains((it as Teacher).prop1)
    }
    else
    {
        false
    }
}.forEach{
    if(it is Student)
    {
        total += (it as Student).prop2.toLong()
    }
    else if(it is Teacher)
    {
        total += (it as Teacher).prop2.toLong()
    }

}
println(total)  //print 6 in this example

这很难看。最好让StudentTeacher继承一个公共超类或实现一个公共接口

答案 2 :(得分:0)

尝试一下:

object Test {

    private fun isContains(school: Set<Int>, any: Any) = when (any) {
        is Student -> school.contains(any.prop1)
        is Teacher -> school.contains(any.prop1)
        else -> false
    }

    private fun value(any: Any) = when (any) {
        is Student -> any.prop2
        is Teacher -> any.prop2
        else -> throw NoWhenBranchMatchedException("any should be Student or Teacher")
    }

    @JvmStatic
    fun main(args: Array<String>) {
        val school = setOf(1, 2)
        val list = listOf(Student(1, 1), Student(2, 2), Student(3, 3), Teacher(1, 1), Teacher(2, 2), Teacher(3, 3))

        val total = list.filter {
            isContains(school, it)
        }.map {
            value(it)
        }.sum()

        println("Total: $total")
    }

    private class Student(val prop1: Int, val prop2: Int)

    private class Teacher(val prop1: Int, val prop2: Int)
}