【问题标题】:If/Else alternativeIf/Else 替代方案
【发布时间】:2016-08-15 00:23:18
【问题描述】:
public boolean typeMatch(char c1, char c2) {

    if (c1 == '{' || c1 == '}') {
        return (c2 == '{' || c2 == '}');
    } else if (c1 == '(' || c1 == ')') {
        return (c2 == '(' || c2 == ')');
    } else if (c1 == '[' || c1 == ']') {
        return (c2 == '[' || c2 == ']');
    } else {
        return false;
    }
}

我的程序中有上述代码,我想知道是否有更好的方法来实现此方法,而无需使用大量 if/else 语句。

【问题讨论】:

  • @Tom 我的错,没看到变量差异

标签: java if-statement


【解决方案1】:

字符数组数组中的字符对

您可以将您的符号对(打开和关闭)提取到char[][],然后遍历该数组以测试匹配。比如,

static final char[][] pairs = { { '{', '}' }, { '(', ')' }, { '[', ']' } };

public boolean typeMatch(char c1, char c2) {
    for (char[] pair : pairs) {
        if (c1 == pair[0] || c1 == pair[1]) {
            return c2 == pair[0] || c2 == pair[1];
        }
    }
    return false;
}

字符串数组中的字符对

或者,如果我们使用String(s ) 和String.indexOf(int)2。比如,

public boolean typeMatch(char c1, char c2) {
    String[] pairs = { "{}", "()", "[]" };
    for (String pair : pairs) {
        if (pair.indexOf(c1) != -1) {
            return pair.indexOf(c2) != -1;
        }
    }
    return false;
}

1这绝不是一件坏事
2链接的 Javadoc 部分表示,在任何一种情况下,如果此字符串中没有出现此类字符,则返回 -1

【讨论】:

    【解决方案2】:

    Elliott's solution 会比我的好很多,但我想我会玩得开心。

    private static final Map<Character, Set<Character>> pairMap;
    
    public boolean typeMatch(char c1, char c2) {
        Set<Character> s = pairMap.get(c1);
        return s != null && s.contains(c2);
    }
    
    static {
        pairMap = new HashMap<>();
        register(makeSet('{', '}'));
        register(makeSet('(', ')'));
        register(makeSet('[', ']'));
    }
    
    private static Set<Character> makeSet(char... chars) {
        Set<Character> s = new HashSet<>(chars.length, 1.0f);
        for (char c : chars) {
            s.add(c);
        }
        return s;
    }
    
    private static void register(Set<Character> s) {
        for (Character c : s) {
            pairMap.put(c, s);
        }
    }
    

    此解决方案的内存要求非常高。它唯一需要推荐的是,如果您需要处理大量字符等价类而不是三对,它将在执行时间方面更好地扩展。此外,它可以泛化为处理除char 之外的其他类型(或者,准确地说,Character)。

    【讨论】:

      【解决方案3】:
      private static final String PAIRS = "{}()[]";
      public boolean typeMatch(char c1, char c2) {
          int indexOfC1 = PAIRS.indexOf(c1);
          int indexOfC2 = PAIRS.indexOf(c2);
          return indexOfC1 >= 0 && indexOfC2 >= 0 && (indexOfC1 / 2 == indexOfC2 / 2);   
      }
      

      有点棘手,也许......

      【讨论】:

      • 您还必须测试 indexOfC2 >= 0,因为 -1 / 2 为 0。
      • 或者甚至 (PAIRS.indexOf(c1) ^ PAIRS.indexOf(c2) &amp; -2) == 0 用于单线。
      • 哦,除了我的建议与 Christian 指出的错误相同,没有考虑 -1。
      • @Christiand'Heureuse 已修复。我一直忘记/% 的这些愚蠢的C 风格定义不具备它们应有的良好数学属性。
      • 是的,好的,所以我的单排线坏了。是的,&amp; 优先于 ^,这意味着我看起来很愚蠢。这里有一个教训。当一个人试图变得太聪明时,肯定会出错。这就是 Elliott 的解决方案如此出色的原因 - 它聪明。它非常清晰,易于维护,并且有效
      【解决方案4】:

      不是最易读的,但我尝试使用位运算符来做这件事很有趣,我想我会发布它

      public boolean typeMatch(char c1, char c2) {
          int xor = c1 ^ c2;
          if(xor == 6) { // 2 apart
              return c1 == '{' || c1 == '}' || c1 == '[' || c1 == ']';
          } else if(xor == 1) { // 1 apart
              return c1 == '(' || c1 == ')';
          } else if(xor == 0) { // same
              return c1 == '(' || c1 == ')' || 
                      c1 == '{' || c1 == '}' || c1 == '[' || c1 == ']';
          }
          return false;
      }
      

      至少应该很快……

      【讨论】:

        【解决方案5】:

        这里已经有一个公认的答案,这是一个很好的答案,但它非常针对手头的问题。

        对于那些通过寻找更通用的解决方案来到这里的人,我想提供我最喜欢的模式来消除 if/else 链:

        boolean result = false;
        do {
           if(condition1) {
              result = true;
              break;
           }
        
           if(condition2) {
             break;
           }
        
           // etc.
        
        } while(false);
        
        return result;
        

        这当然可以推广到任何返回类型。

        【讨论】:

          猜你喜欢
          • 2010-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-30
          • 2014-05-22
          • 1970-01-01
          • 2013-09-16
          • 1970-01-01
          相关资源
          最近更新 更多