【问题标题】:Is there a more efficient way to compare 3+ items in an If statement?有没有更有效的方法来比较 If 语句中的 3+ 个项目?
【发布时间】:2014-04-06 04:30:16
【问题描述】:

我正在编写一个班级作业程序,我想比较数组中的多个项目是否相等。我的陈述基本上是这样的:

if (a == b && b == c && c == d && d == e && e == f) {
   // do stuff
}

这个条件看起来非常冗长,我想知道是否有更短的方法来写这个。

【问题讨论】:

  • 您想比较所有元素是否相等,或者您想要完成什么?
  • 如果它们在一个数组中,我建议你创建一个单独的方法来比较它们。元素类型是什么?如果数组为空,你希望发生什么?
  • 设置:public <T> Set<T> GetSetFromArray(T[] array) { return new HashSet<T>(Arrays.asList(array)); } 然后拨打if (GetSetFromArray(T[]{a, b, c,d}).size() == 1){}
  • @GrijeshChauhan 这太过分了。
  • 我想比较一个数组中的多个元素(特别是int),看看它们是否相等。我想创建一个单独的方法是最好的,因为它会减少很多混乱。至于数组为空,我想我可以假设为了赋值,数组不会为空。

标签: java if-statement conditional-statements


【解决方案1】:

这可能看起来冗长,但至少它是相当有效且清晰

为了简洁,不要过度优化代码。

你可以很容易地创建一个辅助函数

boolean allEqual(Object ... objs) {
    for(int i = 1; i < obj.length; i++) {
      if (!objs[i].equals(objs[0])) {
        return false;
      }
    }
    return true;
}

但这会创建额外的对象;特别是原始值:

if (allEqual(1.1,2.1,3.1,4.1))

将创建 5 个需要进行垃圾回收的对象。

确保您确实想要== 而不是equals

【讨论】:

  • 他说元素当前在一个数组中,因此您的方法可以直接接收该数组,避免创建新对象。
【解决方案2】:

这可以在 Java 8 中完成,前提是您已经有一个数组:

int[] numbers = {1, 2, 3, 4, 5};
if (Arrays.stream(numbers).allMatch(i -> (i == numbers[0]))) {
    //they are equal
}

它的作用是:

  • 它将您的数组封装在 IntStream 中(它创建额外的对象,除了 IntStream
  • 它检查IntPredicate 上的所有对象是否都返回true。
  • IntPredicatei -&gt; (i == numbers[0]),它将i 映射到(i == numbers[0])

建议将其封装在一个辅助方法中,如果数组为空,您需要提前保释,如下所示:

public static boolean allEquals(final int[] input) {
    return (input.length > 0 && Arrays.stream(input).allMatch(i -> i == input[0]));
}

这取决于它是否应该返回 truefalse 如果没有输入...那么一切都相等吗?

请注意,您需要为您使用的所有原语制作此代码。另外,您还可以提供通用版本:

public static <T> boolean allEquals(final T[] input) {
    return (input.length > 0 && Arrays.stream(input).allMatch(i -> i.equals(input[0])));
}

现在,如果您没有合适的结构,这意味着它们很可能只是变量,那么将需要决定您是需要额外的性能还是可以忍受传递它们的开销作为 varargs 输入,它隐式地创建一个数组,其代码将非常相似:

public static <T> boolean allEquals(final T... input) {
    return (input.length > 0 && Arrays.stream(input).allMatch(i -> i.equals(input[0])));
}

您几乎可以肯定地忍受额外的开销,只有在性能非常关键的应用程序中,如果您的方法被执行多次,您需要小心。

【讨论】:

    【解决方案3】:

    我的建议是创建一个集合,如果它的大小为 1,则所有元素都相等,否则不:

    public static < E > boolean areAllEqual( E[] inputArray ){
        Set<E> mySet = new HashSet<E>(Arrays.asList(inputArray));
        return mySet.size() == 1;
    }    
    

    以下是完整的代码示例:

    import java.util.*;
    public class HelloWorld{
        public static < E > boolean areAllEqual( E[] inputArray ){
            Set<E> mySet = new HashSet<E>(Arrays.asList(inputArray));
            return mySet.size() == 1;
        }    
         public static void main(String []args){
            Integer[] intArray = { 1, 2, 3, 4, 5 };
            Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
            Character[] charArray = { 'H', 'H', 'H', 'H', 'H' };
    
            System.out.println("It should work");
            if (areAllEqual(intArray))
                System.out.println("inarray Yes");
            else
                System.out.println("inarray No");
    
            if (areAllEqual(doubleArray))
                System.out.println("doubleArray Yes");
            else
                System.out.println("doubleArray No");
    
            if(areAllEqual(charArray))
                System.out.println("charArray  Yes");
            else
                System.out.println("charArray  No");                            
         }
    }
    

    输出:

    It should work
    inarray No
    doubleArray No
    charArray  Yes  // all elements in char array are eq
    

    【讨论】:

    • 我喜欢这种方法,出于几个原因,我倾向于将集合用于类似的事情 - 可读性、稳定性和效率。旁注:我建议在if 语句之后使用{},即使正文只包含一行。
    • @MarounMaroun 我们可以做类似int a = 1, b = 1, c = 1, e = 1; 然后if(areAllEqual(int[]({a, b, c, d, e}))) 的事情吗?就像我可以在 C99 (int []){2, 4} 中使用复合文字一样,例如here
    • OK 可以像if (areAllEqual(new Integer[] { a, b, c, d, e }))一样调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多