【问题标题】:Simplifying/optimizing massive if...else if...else statement(s)简化/优化大量 if...else if...else 语句
【发布时间】:2020-11-23 03:46:47
【问题描述】:

好吧,基本上,我有一些代码使用 contains() 方法来检测两个字符串中是否存在特定字符。对于额外的上下文,this question 是一个很好的资源,可以帮助我了解我遇到了什么样的问题(第三个解决方案也是我为此研究过的)。无论如何,这是我的一些代码:

// code up here basically just concatenates different
// characters to Strings: stringX and stringY

if (stringX.contains("!\"#")) {
} else if (stringX.contains("$%&")) {
} else if (stringX.contains("\'()")) {
} else if (stringX.contains("!$\'")) {
} else if (stringX.contains("\"%(")) {
// literally 70+ more else-if statements
}

if (stringY.contains("!\"#")) {
} else if (stringY.contains("$%&")) {
} else if (stringY.contains("\'()")) {
} else if (stringY.contains("!$\'")) {
} else if (stringY.contains("\"%(")) {
// literally 70+ more else-if statements, all of which are
// exactly the same as those working with stringX
}

我对 Java 编程还是很陌生,所以我不确定我应该如何去做。也许这不是问题?另外,如果我可以在不使用 RegEx 的情况下解决这个问题,那就更好了;在这一点上,我对它不是很了解。但如果唯一合理的解决方案是利用它,我显然会这样做。

编辑:所有这些 else-if 语句中的代码彼此之间不会有太大的不同;基本上只是一个System.out.println(),其中包含一些关于 stringX/stringY 包含的字符的信息。

【问题讨论】:

  • 每种情况的代码有何不同?
  • 哦,废话,我会更新我的帖子以更好地解释这一点。
  • 我们需要查看各种 if-else 块中的代码。
  • 更一般地说,这里的首选答案是用多态替换条件。具体来说,您似乎有一个Map<String, Consumer<String>>map.entrySet().stream().filter(e -> stringX.contains(e.getKey())).findFirst().ifPresent(e -> e.getValue().accept(stringX)); 之类的东西。
  • 是否需要此优先级?即,它只会在没有找到!"# 时搜索$%&

标签: java performance if-statement optimization


【解决方案1】:

多次编写相同的代码应该会立即在您的脑海中敲响警钟,将代码移动到函数中以便可以重复使用。

至于简化表达式,最好的方法可能是将您要查找的模式存储为一个数组,并根据您的条件迭代该数组。

private static final String[] patterns = new String[] {"!\"#", "$%&", "\'()", "!$\'", "\"%(", ...};

private static void findPatterns(String input) {
    for (String pattern : patterns) {
        if (input.contains(pattern) {
            System.out.println("Found pattern: " + pattern);
        }
    }
}

// Elsewhere...
findPatterns(stringX);
findPatterns(stringY);

这种模式在函数式和函数式语言中尤其常见。 Java 8 流就是一个很好的例子,所以你也可以这样做

List<String> patterns = Arrays.asList("!\"#", "$%&", "\'()", "!$\'", "\"%(", ...);
patterns.stream()
    .filter(pattern -> stringX.contains(pattern))
    .forEach(pattern -> System.out.println("Found pattern: " + pattern));

【讨论】:

  • 鉴于功能不完全相同,地图可能会成为选择的结构。
  • @Elan Hamburger |谢谢你,Mx。汉堡包。我认为对于我的简单项目,前一个选项将是合适的,并不是说其他​​任何答案都是错误的或比这个更糟糕。只有一个问题:如果我将patterns 设为一个二维数组,我可以用for (String pattern : patterns[a][b]) 引用特定的字符组合吗?根据我的 Java 笔记本,我可以使用多个 for 循环来执行此操作,但不能使用单个 for-each 循环。这对我来说不会有太大的不同,所以我真的很好奇。
  • 没关系,别管那个; this answer 是一个很好的资源。再次感谢!
【解决方案2】:

可以简单地列出您的案例。然后使用java 8 stream filter

List<String> pattems = Arrays.asList("!\"#", "$%&", ...);
Optional<String> matched = pattems.stream().filter(p -> stringX.contains(p));
if(matched.isPresent()) {
   System.console().printf(matched.get())
}

java stream 可以让你的表现达到slower 但不会太多

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    相关资源
    最近更新 更多