【问题标题】:String contains vs List<String> contains字符串包含 vs List<String> 包含
【发布时间】:2012-12-16 13:38:42
【问题描述】:

假设您想测试输入是否是几个常量字符串之一,并且忽略性能,它是否是一种反模式:

if ("yes oui ja da".contains(answer)) {
    // answer was in the affirmative
}

而不是更传统的:

private static List<String> affirmativeAnswers = Arrays.asList("yes", "oui", "ja", "da");

if (affirmativeAnswers.contains(answer)) {
    // answer was in the affirmative
}

它的代码少了很多,也更容易阅读,但它是“黑客”吗?

编辑:

为了更安全,如果担心部分匹配,可以这样编码:

if (",yes,oui,ja,da,".contains(',' + answer + ',')) 

还是少了很多代码(虽然越来越丑)

【问题讨论】:

  • 当您使用regex 在没有boundary 的情况下搜索特定模式时会发生同样的事情。这不是黑客攻击。这是一个错误..

标签: java coding-style contains


【解决方案1】:

出于各种原因,我认为这是一个丑陋的 hack:

  • 它对意外输入不可靠。例如("yes oui ja da".contains(" ")) 将返回 true - 可能不是您想要的。这是我认为最大的问题。即使您开始添加更多技巧(例如最近编辑中的逗号),您仍然需要考虑令人讨厌的极端情况。
  • 在一般情况下它的性能不高 - 如果您有中等/大量的可能性进行测试,您可能最好检查 HashMapHashSetO(1) 而不是O(n) 用于扫描连接的字符串。
  • 这可能会使没有经验的编码人员/未来的维护人员感到困惑。如果您希望代码可维护,请不要使用巧妙的技巧。
  • 它不适合未来的重构(例如字符串的国际化?在运行时动态更改可能性列表?)

【讨论】:

    【解决方案2】:

    另外,AFAIK,String contains 方法使用正则表达式来检查子字符串是否是字符串的一部分。与搜索列表(AFAIK)相比,此操作的成本很高。所以IMO,现在最好使用列表,不是吗? ;)

    【讨论】:

    • “另外,AFAIK,String contains 方法使用正则表达式...” 不,它没有。 当然它没有。它没有必要。 contains 只是 indexOf(...) &gt; -1 的包装,indexOf 也不使用正则表达式。
    • 对不起,我想我把包含和全部替换混淆了。谢谢指正。
    • @ 表达式:嗯,是的,replaceAll 使用正则表达式,因为你给它的参数是一个模式字符串。
    【解决方案3】:

    尽可能删除依赖项

    在我看来,这不是最佳做法。最佳实践将允许消除对接受字符串的依赖。在这种情况下,依赖项是这个("yes", "oui", "ja", "da") 字符串列表。但是,如果要将字符串列表的依赖项移至服务或数据库,则将其集成到接受 List&lt;string&gt; 的方法中将非常容易,因为这很明显,而在尝试集成时可能会出现问题一个只需要 string 的方法。

    牢记范围

    与往常一样,这取决于范围。如果你只需要一次做这件小事,而且它是一个非常小的项目的一部分,那么它真的没什么区别。但是,如果这是一个不小的项目的一部分,那么如果没有遵循最佳实践,则可能需要在未来进行重构。

    让编译器优化代码

    关于它需要的代码量,您不必太担心。更重要的是它的可读性。编译器将使代码尽可能高效,因为这是它的职责。不要尝试编写类似于编译器的代码,因为随着更好的方法出现,编译器将使用它们,而模拟代码将保持不变。

    【讨论】:

    • 我认为它比列表版本更具可读性,这就是我偶尔使用它的原因
    • @Bohemian - 好吧,作为 1 班轮,我可以看到这一点,但是如果您将其分解为一个方法,那么如果它接受字符串列表,则签名将更具可读性。通常,当我发现自己不止一次地使用一个过程时,我会将它变成一种方法或使用设计模式来封装它。这样就没有复制粘贴错误的余地,将来可以扩展功能,并且易于测试。
    • 您不会费心创建 s 方法来接受如果字符串和字符串的欲望;您只需将其嵌入广告 list.contsins(sting)
    【解决方案4】:

    如果要检查句子中是否存在字符串,则
    string.contains(string) 是可行的。

    否则,如果您想检查整个字符串是否相等,那么,
    list.contains(string) 是可行的。

    【讨论】:

      【解决方案5】:

      ...这是对语言的滥用...

      “Java - 他不在乎!!”。但是“哇!!讨厌!!”1.

      但是说真的,您的目标应该是让您的代码易于阅读和维护。 (或者高性能......如果这很重要。)

      使用最少的击键次数来表达某些东西的棘手、晦涩的代码不是上述的。这是一种糟糕的风格......即使你的代码在功能上是正确的。


      1 - 如果你在过去一年左右一直生活在岩石下......我是在暗示这个 - http://knowyourmeme.com/memes/honey-badger

      【讨论】:

      • 仅供参考,我认为 hack 很容易阅读。这就是我有时使用它的原因。
      • 如果您认为它易于阅读,为什么要征求我们的意见?但无论如何,我不同意这一点。如果您已经使用过,并且可以识别成语,它只会很容易阅读。想想其他人阅读你的代码......
      • 现在回想我的建议,我有点害怕。
      猜你喜欢
      • 2016-06-20
      • 2013-03-14
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 2016-09-16
      • 2011-12-07
      • 2013-03-30
      相关资源
      最近更新 更多