Java 是否有干净的语法来检查多个变量是否都具有相同的值?

Java 是否有干净的语法来检查多个变量是否都具有相同的值?,java,Java,我们有n个变量X={x1,x2,…xn}它们不在任何结构中 例如,在python中,我可以这样做:if(x1==x2==x3==xn): 在java中我必须做:if((x1==x2)&&(x2==x3)&&(x3==xn)): 你知道改进这种语法的简单方法吗?(想象一下很长的变量名和很多变量名) 谢谢。不幸的是,没有,没有语法糖。这是关于Java的常见抱怨。如果您有很多这样的变量,您是否考虑过将它们放在一个集合中,而不是将它们作为单独的变量?在这一点上有多种选择 如果您发现自己经常这样做,那么可

我们有n个变量
X={x1,x2,…xn}
它们不在任何结构中

例如,在python中,我可以这样做:
if(x1==x2==x3==xn):

在java中我必须做:
if((x1==x2)&&(x2==x3)&&(x3==xn)):

你知道改进这种语法的简单方法吗?(想象一下很长的变量名和很多变量名)


谢谢。

不幸的是,没有,没有语法糖。这是关于Java的常见抱怨。

如果您有很多这样的变量,您是否考虑过将它们放在一个集合中,而不是将它们作为单独的变量?在这一点上有多种选择

如果您发现自己经常这样做,那么可能需要编写帮助器方法,可能需要使用varargs语法。例如:

public static boolean areAllEqual(int... values)
{
    if (values.length == 0)
    {
        return true; // Alternative below
    }
    int checkValue = values[0];
    for (int i = 1; i < values.length; i++)
    {
        if (values[i] != checkValue)
        {
            return false;
        }
    }
    return true;
}
在这两种情况下,请与以下内容一起使用:

if (HelperClass.areAllEqual(x1, x2, x3, x4, x5))
{
    ...
}

您可以创建如下实用程序方法:

public boolean allEqual(Object... objs) {
    if(objs.length < 2) return true; // 0 or 1 objects are all equal
    Object key = objs[0]; // pick one
    for(Object o : objs) if(!o.equals(key)) return false;
    return true;
}
if (areAllEqual(x1, x2, x3, x4, x5)) {
    // do something
}
简化许多样板逻辑。那就走吧

if(allEqual(x,x1,x2,x3))
很明显,这两者是相互排斥的(它们是明显的模棱两可),但你可以这样做
allEqual
allEqualWithKey

您可以编写一种方法,使其看起来不那么麻烦:

boolean areAllEqual(Object... values) {
    if (values.length < 2) {
        return true;
    }

    for (int i = 1; i < values.length; i++) {
        if (!values[i].equals(values[0])) {
            return false;
        }
    }

    return true;
}

编辑太慢…!:-(

如果您不喜欢键入,可能会丢失嵌套的Parethese:

if(x1 == x2 && x2 == x3 && x3 == xn);

类似于@Jon的解决方案,但更短

public static boolean areAllTheSame(int value, int... values) {
    for (int i: values) if(value != i) return false;
    return true;
}

实现这一点的另一种快速方法是通过
数组
->
列表
->
哈希集
转换路径,如下所示:

标准Java:

if(new HashSet<Object>(Arrays.asList(x1, x2, x3, x4, x5)).size() == 1) {

}
不过,上述解决方案本身看起来不太干净,因此它应该被隔离到一个单独的实用程序方法中,并有一个合理的名称(在这种情况下,您最好首先使用Peter Lawrey或Jon Skeet的解决方案)

我还希望这种方法至少会对性能造成微小的影响,因为很明显,必须实例化和填充多个
集合


因此,重申一下-只有当你下定决心要打一条直线时,才使用此解决方案。

使用以下截取的代码,你可以识别重复的
Map
值:

    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = 1;
        int d = 3;

        Collection<Integer> collectionOfValues = List.of(a, b, c, d);

        Map<Integer, List<Integer>> groupedByUniqueKeys = collectionOfValues.stream()
            .collect(
                groupingBy(
                    Function.identity()));

        System.out.println(groupedByUniqueKeys);
        // {1=[1, 1], 2=[2], 3=[3]}
    }
publicstaticvoidmain(字符串[]args){
INTA=1;
int b=2;
int c=1;
int d=3;
Collection collectionOfValues=列表(a、b、c、d);
Map groupedByUniqueKeys=collectionOfValues.stream()
.收集(
分组依据(
Function.identity());
System.out.println(按唯一键分组);
// {1=[1, 1], 2=[2], 3=[3]}
}

1
的映射将包含具有相等值的变量值(
a
c
).

我喜欢已经提出的样板逻辑,但通常列表中的任何参数都可以是
null
,这可能会导致抛出
NullPointerException
。因此,我们应该首先测试
null
,并在适当的情况下使用
=
来比较对象引用:

public static boolean allEqual(Object key, Object... objs) {
    for(Object o : objs)
        if((key != null && !key.equals(o)) || key != o) return false;
    return true;
}

在Java 8中,这可以使用
流作为一个单行程序来完成:

boolean allEqual = Stream.of(x1, x2, x3, x4).distinct().count() == 1;

基本上,
distinct
通过检查每个元素是否相等来过滤流,以便只保留唯一的元素。如果过滤后只剩下一个元素,则表示所有原始元素都相等。

/*
*reference-要与之进行比较的基本字符串
*条目-用于比较的所有其他对象
*/
公共静态布尔allEqual(字符串引用、字符串…条目){
返回Arrays.stream(条目)
.allMatch(条目->对象.equals(引用,条目));
}
/*
*方法可以泛化为使用而不是字符串
*/
公共静态布尔allEqual(T引用,T…条目){
返回Arrays.stream(条目)
.allMatch(条目->对象.equals(引用,条目));
}
公共静态void main(字符串[]args){
System.out.println(allEqual(“X”、“X”、“X”、“X”);//true
System.out.println(allEqual(“X”、“X”、“Y”);//false
System.out.println(allEqual(“X”);//true
System.out.println(allEqual(10,10,9));//false
System.out.println(allEqual(10,10));//true
System.out.println(allEqual(10,新整数[]{10,10,10}));//真
}

只是为了更新这些答案(JavaSE9)

对于数学家来说,这是非常有意义的。(在这种情况下,我称自己为数学家。)

(显然,
Integer
s、
Integer[]
Set
以及
Set
的内部都存在一种或另一种装箱开销)

Edit:Stuart Marks指出,如果存在重复元素,
Set.of
将抛出
illegargumentexception
。备选方案:

Set.copyOf(Arrays.asList(x1,x2,...xn)).size() == 1
或者根据您对清洁的定义:

copyOf(asList(x1,x2,...xn)).size() == 1

(假设静态导入过多。)

这不是您想要的,但这需要某种数据结构,而不是一堆自变量。太糟糕了。我会研究一下。谢谢!在java中,(x1==x2==x3==x4)将返回test.java:8:不可比较的类型:boolean和int System.out.println(x1==x2==x3==x4)^Test.java:8:不可比较的类型:boolean和int System.out.println(x1==x2==x3==x4);我在python中说过我们可以这样做(x1==blablabla)你的观点是什么Leo?@Leo如果你试图用一组布尔函数来做这件事,那就更危险了。如果x1,x2,x3,x4是布尔函数,它们会编译,但有一个无声的bug。
x1==x2==x3
(x1==x2)==x3
这与我们想要的有很大的不同!嗯,也许这在我的大学里很常见?谢谢你的另一种观点,@Jon.在Java的几年里从未需要过这个。可爱,但有很多
boolean allEqual = Stream.of(x1, x2, x3, x4).distinct().count() == 1;
/*
* reference - basic String to compare against
* entries - all other objects for comparison
*/
public static boolean allEqual(String reference, String... entries) {
        return Arrays.stream(entries)
                .allMatch(entry -> Objects.equals(reference, entry));
}

/*
* Method can be generalized to use <T> instead of String
*/
public static <T>boolean allEqual(T reference, T... entries) {
    return Arrays.stream(entries)
            .allMatch(entry -> Objects.equals(reference, entry));
}

public static void main(String[] args) {
    System.out.println(allEqual("X", "X", "X", "X")); // true
    System.out.println(allEqual("X", "X", "Y"));      // false
    System.out.println(allEqual("X"));                // true

    System.out.println(allEqual(10, 10, 9));          // false
    System.out.println(allEqual(10, 10));             // true
    System.out.println(allEqual(10, new Integer[] {10, 10, 10})); // true
}
 Set.of(x1,x2,...xn).size() == 1
Set.copyOf(Arrays.asList(x1,x2,...xn)).size() == 1
copyOf(asList(x1,x2,...xn)).size() == 1