【问题标题】:Find 2 elements in list and return true kotlin?在列表中找到 2 个元素并返回真正的 kotlin?
【发布时间】:2020-07-27 19:37:59
【问题描述】:

我有列表,我需要检查它是否包含 2 个特定字符串。 我有以下代码并希望进一步优化它

fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
    var tve = false
    var avod = false
    if (subscriptionPlans.size > 0) {
        for (i in subscriptionPlans.indices) {
            if (subscriptionPlans[i] != null &&
                    subscriptionPlans[i].planMonetizationModel != null) {
                if (subscriptionPlans[i].planMonetizationModel.equals("TVE", ignoreCase = true)) tve = true
                if (subscriptionPlans[i].planMonetizationModel.equals("AVOD", ignoreCase = true)) avod = true
            }
        }
    }
    return tve && avod
}

【问题讨论】:

  • 您想优化代码的哪一方面?时间、空间、代码复杂度、开发时间……?请明确说明。甚至可能是premature optimization 的情况。另外我认为您应该考虑查看列表以外的其他数据结构。那是我的 2 克拉

标签: list kotlin


【解决方案1】:

您可以使用findanyfilter 方法。请检查下面的any 方法应用:

 fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
    var tve = subscriptionPlans.any { it.planMonetizationModel?.equals("TVE") }
    var avod = subscriptionPlans.any { it.planMonetizationModel?.equals("AVOD") }
    return tve && avod
}

【讨论】:

  • 使用subscriptionPlans.any { it.planMonetizationModel.equals("...") } 可能会更简洁。
【解决方案2】:

您要优化什么?

我的自然反应是从最简单的代码开始,大致如下:

fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>)
    = "TVE" in subscriptionPlans
    && "AVOD" in subscriptionPlans

这很简单,易于阅读和理解(非常接近您对函数的描述),而且很难出错。因此,它会节省的时间——以及那些需要调试、维护和增强您的代码的人。 尽可能保持简单通常要好得多。

它也可能比您的实施快一点。部分原因是两个in 检查将在找到匹配项时停止,而不是继续沿着列表的其余部分进行。但部分是因为它更简单——不仅是您的代码,而且它调用的库例程也会更简单,因此运行时将有更多的空间来优化它们。也因为它们会被更频繁地调用,所以运行时将有更多的机会来优化它们。 (JVM 可以做很多优化,也许比你做的更好。通常最好让你的代码保持清晰和直接,以便给它最好的机会。)

如果你认为你还需要它更快,那么第一件事就是做一些性能测试,看看花在那个功能上的时间是否真的对你的整体有很大的影响运行。 (在绝大多数情况下这似乎不太可能。)

如果您已经证明该功能确实一个瓶颈,那么调整实现可能不会有太大收获。不管它如何工作,您仍然需要平均扫描大部分列表,使其 O(n) — 而且这种复杂性通常会超过任何常数因子的改进。

因此,如果您确实在该功能上花费了大量时间,那么我会尝试更改设计,而不是更改实现

例如,如果您将subscriptionPlans 设为Set 而不是List,那么您可以在恒定时间内进行查找,而无需遍历列表。 (除了改变类型之外,上面的代码也可以正常工作!)

或者,如果您需要一个列表(以保留顺序和/或重复项),您可以使用自定义列表包装器来维护两个值的计数,并在从列表中添加/修改/删除项目时更新它们。显然,如果您比修改列表更频繁地进行这些检查(并且事先知道您将检查哪些值),那将是最合适的。

【讨论】:

  • 这很好:)
【解决方案3】:
fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
    var tve = false
    var avod = false
    if (subscriptionPlans.size > 0) {
        for (i in subscriptionPlans.indices) {
            if (subscriptionPlans[i] != null &&
                    subscriptionPlans[i].planMonetizationModel != null) {
                if (subscriptionPlans[i].planMonetizationModel.equals("TVE", ignoreCase = true) && subscriptionPlans[i].planMonetizationModel.equals("AVOD", ignoreCase = true)) {
                return true;
                 }
            }
        }
    }
    return false;
}

【讨论】:

    【解决方案4】:

    如果是重复的过程或用例。

    试试这个:-

    时间复杂度:- O(1)。

    如果您的列表包含自定义对象(如此处所示),您可以在创建对象或设置各种功能时尝试在模型类中管理计数,并在找到匹配项时同时增加计数。

    【讨论】:

      猜你喜欢
      • 2015-10-10
      • 2015-04-27
      • 2023-03-03
      • 1970-01-01
      • 2013-03-24
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多