【问题标题】:Alternative for if(something || somethingElse || somethingElse2 || somethingElse3 ...)if(something || somethingElse || somethingElse2 || somethingElse3 ...) 的替代方案
【发布时间】:2015-02-18 05:38:06
【问题描述】:

我在考虑如何改进我的程序的一部分,但我想知道这种情况是否有“灵丹妙药”。有没有什么策略可以避免像这样大的if OR statements?:

public boolean containsCharOfWord() {
        if (this.name.contains("b") || this.name.contains("a")
                || this.name.contains("c") || this.name.contains("t")
                || this.name.contains("e") || this.name.contains("r")
                || this.name.contains("i") || this.name.contains("a")) {
            return true;
        }
        return false;
    }

谢谢大家!

【问题讨论】:

  • 通用替换,或者专门用于多个String.contains()?
  • 并用这些 char 值制作常量。
  • 对于具体情况,很明显:正则表达式。 name.matches(".*[abceirt].*").
  • 既然您要检查两次name 是否包含a,您确定这是您想要的并且您不是在寻找return name.contains("bacteria");

标签: java performance design-patterns syntax


【解决方案1】:

Guava:

return CharMatcher.anyOf("bacteria").matchesAnyOf(name);

花哨的版本是

private static final CharMatcher VIRUS = CharMatcher.anyOf("bacteria").precomputed();

... return VIRUS.matchesAnyOf(name);

预计算返回更快的匹配器。

【讨论】:

  • + public static final String BACTERIA = "bacteria";
  • 这是一个小细节,真的。它也可能来自配置文件、数据库或其他任何东西。
  • 我看到他们使用排序的char[] 和二进制搜索。这相当有效,但不如BitSet-backed solution 有效。
  • @MarkoTopolnik 也有一个使用BitSetprecomputed 版本(或者其他有效的东西)。
  • 进展顺利...番石榴涵盖了各个角度 :)
【解决方案2】:

首先,删除一个 this.name.contains("a") 因为是重复的

那你可以试试switch(JDK7)

    switch (name) {
    case "b":
      // do something
    case "a":
      // do something
    case "c":
      // do something
    case "t":
      // do something
    case "e":
      // do something
    case "r":
      // do something
    case "i":
      // do something
    }

【讨论】:

  • 与发布的要求相去甚远。使用for 循环并打开String.charAt() 做出明智的回答。
  • 如果名字是“细菌”怎么办?你只匹配一个字符。
  • 你也忘了break;在每种情况下
【解决方案3】:

你应该尝试使用正则表达式

public boolean containsCharOfWord() {
        return this.name.matches("(.*)([bacteria])(.*)");
}

【讨论】:

  • @ZouZou 当然,我刚刚从 OP 复制了代码,没有考虑太多。现已更正。
【解决方案4】:

您想概括名称中可能出现的一系列字符:

public boolean containsAnyCharOfWord(String word) {
    for (int i = 0; i < word.length(); i++) {
        if (this.name.contains(String.valueOf(word.charAt(i)))) {
            return true;
        }
    }
    return false;
}

public boolean containsCharOfWord() {
    return containsAnyCharOfWord("bacteri"); // don't need to check for 'a' twice
}

【讨论】:

  • 工作但很慢 (O(m*n))。而String.valueOf 让它变得非常糟糕。使用String#indexOf(char)
  • OP 并没有要求这个特定问题的最佳解决方案,他问的是“有没有什么策略可以避免像这样的大 if OR 语句?”。这就是我的回答所要解决的问题;其他任何事情都会通过解决非常不同的事情来分散注意力。
【解决方案5】:

没有任何外部库:使用正则表达式匹配/模式匹配:即“我的字符串是否与上述任何字符匹配”?

myString.matches(".*[bacteria].*")

【讨论】:

  • 慢...每次都编译正则表达式。
  • OP 询问的是短代码,而不是快速执行。也可以预编译该模式并应用它。但根据上下文,这可能比问题所保证的代码更多。
  • 是的,很棒的东西。现在它只比 cmets 中的解决方案少了一个编辑。
  • 那你为什么不发布你的解决方案呢?我什至没有看过上面的cmets。
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 2012-10-10
相关资源
最近更新 更多