【问题标题】:Is there a simpler way to check multiple values against one value in an if-statement? [duplicate]是否有一种更简单的方法可以根据 if 语句中的一个值检查多个值? [复制]
【发布时间】:2012-02-16 06:36:18
【问题描述】:

基本上,我想做的是根据给定值检查两个整数,因此,通常你会做的是这样的:

//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);

//the actual thing in question
if(a == 0 || b == 0)
{
//Then do something
}

但是有没有更简洁的格式来做到这一点?可能与此类似(返回错误的操作数类型):

//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);

//the actual thing in question
if((a||b) == 0)
{
//Then do something
}

【问题讨论】:

  • 你为什么想要?
  • 因为那样代码会更好看?
  • 作为一种方法,使包含大量变量检查同一变量的 if 语句变得更加简洁。
  • @grapeot:是一回事;用0 代替x,用ab 代替整数文字。

标签: java


【解决方案1】:

你可以在纯 java 中执行以下操作

Arrays.asList(a, b, c, d).contains(x);

【讨论】:

    【解决方案2】:

    不幸的是,Java 中没有这样的结构。

    如果这种比较在您的代码中很常见,您可以实现一个小函数来为您执行检查:

    public boolean oneOfEquals(int a, int b, int expected) {
        return (a == expected) || (b == expected);
    }
    

    那么你可以这样使用它:

    if(oneOfEquals(a, b, 0)) {
        // ...
    }
    

    如果您不想将自己限制为整数,可以将上述函数设为泛型:

    public <T> boolean oneOfEquals(T a, T b, T expected) {
        return a.equals(expected) || b.equals(expected);
    }
    

    请注意,在这种情况下,Java 运行时将对基本类型(如 int)执行自动装箱和拆箱,这是一种性能损失。

    【讨论】:

    • 是的,但是如果我有 3 个或 4 个或更大数量的变量由于某种原因不在数组中怎么办?我每次都必须重写这个函数以适应不同的输入数量。
    • 不完全是,您可以使用可变长度参数列表:public &lt;T&gt; boolean oneOfEquals(T expected, T... actual) { ... } 和函数体中的 for 循环。如果你想@Amndeep7,我会给你一个例子。
    • 这似乎很容易掌握,但有一个问题,T...实际变成了什么?它是某种列表还是数组或什么?
    • 其实是T[]类型,所以可以像传统数组一样处理:for(T value : actual) { if(value.equals(expected) return true; }
    • 感谢您提供此信息。我也想给你投票,但我仍然没有足够的代表。
    【解决方案3】:

    As referenced from this answer:

    在 Java 8+ 中,您可以使用 StreamanyMatch。类似的东西

    if (Stream.of(b, c, d).anyMatch(x -> x.equals(a))) {
        // ... do something ...
    }
    

    请注意,由于将这些元素包装到流中的开销,这有可能比其他 if 检查运行

    【讨论】:

    • 可以更短:Stream.of(b, c, d).anyMatch(a::equals)
    【解决方案4】:

    我认为是按位或:

    if ((a | b) == 0) . . .
    

    如果您想专门检查 0 会起作用。我不确定这是否会节省任何执行时间。更重要的是,它产生了神秘的代码,这将使该代码的未来维护者诅咒你(即使是你自己)。我建议坚持使用更多类型的选项。

    呸。我误读了 OP 的原始逻辑。

    再来一次……

    如果您想测试多个变量中的任何一个是否等于预期值,通用函数可能会起作用:

    public <T> boolean exists(T target, T... values) {
        for (T value : values) {
            if (target == null) {
                if (value == null) {
                    return true;
                }
            } else if (target.equals(value)) {
                return true;
            }
        }
        return false;
    }
    

    这适用于任意数量的一种类型的对象。基元将被自动装箱,因此它也可以与它们一起使用。您的原始代码将类似于:

    if (test(0, a, b)) {
        // do something
    }
    

    (迫切需要一个更好的方法名称,甚至考虑这是否比您现在拥有的方法有所改进。即使测试扩展到 3 或 4 个变量,我也质疑这种东西的必要性。)请注意,这也适用于数组:

    int[] values = { . . . };
    if (test(0, values)) { . . .
    

    它可用于测试一个数组(或任何变量集合)是否为null

    【讨论】:

    • 但是有没有办法概括这一点?例如,我不仅可以检查 0,还可以将这些值与另一个变量进行比较,比如一个名为“c”的 int?
    • 不起作用 - 如果a=1; b=0;,您的测试失败,原始测试通过。
    • 不,这是相反的,它可以取代a == 0 &amp;&amp; b == 0。使用按位和没有帮助(例如,对于两个不同的幂次方)
    • @grapeot 模二次幂算术除数为零,这意味着a*b=0 并不意味着ab 为零。
    • @grapeot no.. 因为那不正确。如果a*b 恰好为零,则ab 的值使得ab 都不为零。例如a=0x80000000 b=2
    【解决方案5】:
    if(a == 0 || b == 0)
    {
    //Then do something
    }
    

    为什么不保持可读性?什么是简洁的?另一方面,

    a = (int)(Math.random()*5);
    

    涉及不必要的演员表。为什么不直接使用Random 并调用nextInt()

    【讨论】:

    • 我从不知道那个类,我一直被教导使用 Math.random(),特别是因为它可以很容易地适应我希望创建的值范围。
    • 使用 Random 很容易对值进行范围限制。例如1-6之间的随机数:1 + myRand.nextInt(5);
    【解决方案6】:

    对于这个例子,你可以这样做

    if (a * b == 0)
    

    或更多变量

    if (a * b * c * d == 0)
    

    虽然更简洁,但可能不太清楚。对于较大的值,您需要强制转换为 long 以避免溢出。

    【讨论】:

    • 对于两个以上的变量,您可能需要比 long 更大的东西,如果它们都可以是完整范围的话..
    • 非常正确。对于较大的类型,您需要检查每一个。但是对于0 - 4 的值,它应该是安全的。
    【解决方案7】:

    你可以把整数放在一个集合中,看看它是否包含给定的值。 Using Guava:

    if(newHashSet(a, b).contains(0)){
        // do something
    }
    

    但在这种情况下,两个简单的 int 比较可能更容易理解。

    【讨论】:

      【解决方案8】:

      这是对@buc 答案的修改,可以接受任意数量的任何参数:

      public <T> boolean oneOfEquals(T expected, T... os) {
          for (T o : os) {
              if (expected.equals(o)) return true;
          }
          return false;
      }
      

      【讨论】:

        【解决方案9】:

        即使您按照 Ted 的建议使用按位运算,表达式也不相等,因为一个要求至少 一个 变量为零,而第二个要求 两者 其中为零。

        关于您的问题,Java 中没有这样的快捷方式。

        【讨论】:

          【解决方案10】:

          你可以试试这个代码:

          public static boolean match (Object ref, Object... objects)
          {
              if (ref == null)
                  return false;
              //
              for (Object obj : objects)
                  if (obj.equals (ref))
                      return true;
              //
              return false;   
          }   //  match
          

          所以如果你可以这样检查:

          if (match (reference, "123", "124", "125"))
              ;   //  do something
          

          【讨论】:

            【解决方案11】:

            在 Java 8 中,我们可以使用以下方法实现相同的目的:

            private boolean methodName(int variant,int... args){
                    if(args.length > 0){ return Arrays.stream(args).anyMatch( x -> x == variant); }
                    return false;
                }
            

            如果变体匹配任何可能的输入,给定的方法将返回 true。这用于或条件。

            同样,如果你想做 &&(and) 条件,那么你只需要使用其他 Java 8 方法:

            注意:这些方法将 Predicate 作为参数。

            anyMatch:当第一个谓词返回 true 时返回 true,否则返回 false。

            allMatch:如果所有谓词都返回true,则返回true,否则返回false。

            noneMatch:如果没有谓词返回 true,则返回 true,否则返回 false。

            性能说明:当您有足够的数据量时,这很好 检查,因为它有一些开销,但是当您使用它时效果非常好 这对于足够数量的数据。正常的方式只适合两个人 条件。

            【讨论】:

              【解决方案12】:

              没有特殊的语法。你可以为此做一个函数。假设至少 Java 1.5:

              public <T> boolean eitherOneEquals(T o1, T o2, T expectedValue) {
                return o1.equals(expectedValue) || o2.equals(expectedValue);
              }
              
              if(eitherOneEquals(o1, o2, expectedValue)) {
                 // do something...
              }
              

              【讨论】:

                猜你喜欢
                • 2020-10-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多