【问题标题】:Create method with generic parameter for repeated actions为重复操作创建具有通用参数的方法
【发布时间】:2017-12-12 22:08:04
【问题描述】:

我的代码有以下方法:

fun saveArticles(data: JSONArray) {
    var active = String()
    for (i in 0..data.length().minus(1)) // create string

    val articles = Select.from(Article::class.java).list()

    val iterator = articles.iterator()
    while (iterator.hasNext()) {
        val article = iterator.next() as Article
        if (!active.contains(Regex(article.id.toString()))) article.delete()
    }
}

fun saveDossiers(data: JSONArray) {
    var active = String()
    for (i in 0..data.length().minus(1)) // create string

    val dossiers = Select.from(Dossier::class.java).list()

    val iterator = dossiers.iterator()
    while (iterator.hasNext()) {
        val dossier = iterator.next() as Dossier
        if (!active.contains(Regex(dossier.id.toString()))) dossier.delete()
    }
}

fun saveVideos(data: JSONArray) {
    var active = String()
    for (i in 0..data.length().minus(1)) // create string

    val videos = Select.from(Video::class.java).list()

    val iterator = videos.iterator()
    while (iterator.hasNext()) {
        val video = iterator.next() as Video
        if (!active.contains(Regex(video.id.toString()))) video.delete()
    }
}

如您所见,所有方法的作用完全相同。唯一的区别是我目前正在工作的对象的类类型。我可以以某种方式创建一个带有 Class 类型参数的方法,并根据类型更改我需要工作的类吗?像这样的:

fun saveVideos(data: JSONArray, type: Class) {
    var active = String()
    for (i in 0..data.length().minus(1)) // create string

    val list = Select.from(type).list()

    val iterator = list.iterator()
    while (iterator.hasNext()) {
        val item = iterator.next() as type
        if (!active.contains(Regex((item as type).id.toString()))) item.delete()
    }
}

【问题讨论】:

  • 提取delete 到一个接口,让你的所有类实现该接口,并将该接口作为方法的第二个参数传入
  • 我不太清楚“作为第二个参数传入该接口”是什么意思。我很少使用接口,所以我不确定它们是如何工作的。你能举个例子吗?
  • 您还可以为方法添加类型。像这样:inline fun <reified T> save(data: JSONArray) { val list = Select.from(T::class.java).list() } 然后像 save<Video>(data) 一样调用它
  • 只有当你定义的 T 有一个 'id' 方法和一个 'delete' 方法时,提取到一个通用方法才有效。因此,您的所有模型对象都必须扩展具有这些的通用接口/类。然后,您可以按照 Yurii 的建议进行操作,但请记住,这内联了所有代码,因此它并没有真正提取到最终的字节码中。我相信您也可以使用 type: Class as then item as T 执行您建议的操作,但我尚未在编译器中验证。
  • 您可以使用 for 循环来替换迭代器。 For-ins 在 Kotlin 中被编译为迭代器操作。

标签: android performance kotlin generic-programming


【解决方案1】:

您需要提取一个接口并使用reified 泛型。

interface Blabla {
    fun delete()
    val id: Int
}

inline fun <reified T : Blabla>saveVideos(data: JSONArray) {
    var active = String()
    for (i in 0..data.length().minus(1)) // create string

    val list = Select.from(T::class.java).list()

    val iterator = list.iterator()
    while (iterator.hasNext()) {
        val item = iterator.next() as T
        if (Regex(item.id.toString()) !in active) item.delete()
    }
}

这应该可行。

另外,我强烈建议您使用 Kotlin 集合库,像这样。

inline fun <reified T : Blabla>saveVideos(data: JSONArray) {
    val active = ""
    for (i in 0 until data.length()) {} // create string

    val list = Select.from(T::class.java).list()

    list
            .map { it as T }
            .filter { Regex(it.id.toString()) !in active }
            .forEach { it.delete() }
}

您甚至可以将forEach { it.delete() } 替换为forEach(T::delete)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多