检查Java中{3}或更多字符串的相等性

时间:2015-05-31 17:23:52

标签: java string if-statement compare

我知道这是一个非常基本的问题,但我总是想方设法让我的代码尽可能简洁明了。有没有办法比较单个if()语句中三个或更多字符串的相等性?我目前正在使用&&运算符逐步比较每个字符串。但是,正如您可以想象的那样,在调用长变量名称和方法之间,这些if()语句会非常快速地混乱。此外,我计划使用未知数量的这些字符串,并希望避免复杂的for循环,其中嵌套了if()混乱的String a = new String("a"); String b = new String("b"); String c = new String("c"); if(a.equals(b) && b.equals(c)) { doSomething(); } 。这就是我的代码目前的样子:

if(a.equals(b).equals(c)) {
    doSomething();
}

有没有办法,或者我可以使用某种类型的集合,这样我就可以比较这些值:

{
    "mappings": {
        "_default_": {
            "_all": {
                "enabled": true
            },
            "dynamic_templates": [{
                "string_fields": {
                    "match": "*",
                    "match_mapping_type": "string",
                    "mapping": {
                        "type": "string",
                        "fields": {
                            "raw": {
                                "type": "string",
                                "index": "not_analyzed"
                            }
                        }
                    }
                }
            }]
        }
    }
}

7 个答案:

答案 0 :(得分:16)

没有简单的方法来链接这样的equals()命令。为了能够以这种方式链接它们,equals()必须返回对String本身的引用。然而,它不能再返回一个表示比较结果的布尔值。

此外,我将其视为并非特别有问题,以便在第一个示例中分别比较三个字符串。确保您的代码格式良好,即使对于较长的变量名称,它仍然易于理解:

if(myValueAWithALongName.equals(myValueBWithALongName) &&
   myValueBWithALongName.equals(myValueCWithALongName) &&
   myValueCWithALongName.equals(myValueDWithALongName) &&
   ... ) {

或者,您可以使用此线程中提出的其他解决方案之一,并将您的值包装到Collection中并编写辅助方法。但请注意,这可能会对内存使用情况,性能和可能的可读性产生负面影响。

另外,您不应该使用构造函数new String()创建字符串。只需将字符串文字直接分配给您的变量:

String a = "a";

答案 1 :(得分:14)

如果您有多个相同类型的对象,最好将它们组织在数组或列表等数据结构中。假设您有ListString个对象:

List<String> strings = Arrays.asList("a", "b", "a", ...);

您想知道列表中的所有字符串是否彼此相等。这可以通过多种方法完成。可能最短的是:

if(new HashSet<>(strings).size() == 1) {
    // all strings are equal
}

@niceguy提出了更长但更优的解决方案。如果您使用的是Java-8,也可以这样做:

if(strings.stream().distinct().count() == 1) {
    // all strings are equal
}

答案 2 :(得分:3)

根据要比较的String个对象的数量,有不同的方法可以解决此问题。

如果您只有几个String个对象要进行比较,并且您几乎需要在应用程序的一个或两个位置进行此类比较,则可以将代码包装在类中的方法中需要这样的比较,以便代码变得更具可读性:

 public boolean isConditionSatisfied(String a,String b,String c) {
    return Objects.equals(a,b) && Objects.equals(b,c);
 }

然后简化客户端代码并使其更具可读性:

if(isConditionSatisfied(a,b,c)) { //doSomething }

请注意,Objects.equals是自JDK 1.7以来可用的内置方法。与其他答案相比,Object.equals使用NullPointerExcsption来保护你String在我看来是绝对必要的。

如果您发现自己经常需要这种比较(而且不仅仅是String个对象),为什么只寻找一个比较public class ObjectUtils { public static boolean multipleEquals(Object... objectsToCompare) { if (null == objectsToCompare) { return false; } else if (objectsToCompare.length == 0) { return false; } else if (objectsToCompare.length == 1) { return true; } boolean allEqual = true; for (int curr = 1; curr < objectsToCompare.length; ++curr) { if(!Objects.equals(objectsToCompare[0],objectsToCompare[curr])) { allEqual = false; break; } } return allEqual; } } 个对象的解决方案?为什么不找到适用于任何种类或数量的对象的通用解决方案?

String

好,所以你想比较4个if(ObjectUtils.multipleEquals("1","1","1","1") { } 个对象,为什么不呢:

Integer

但是现在你要比较5个if(ObjectUtils.multipleEquals(1,2,3,4,5) { } 个对象,没问题:

if(ObjectUtils.multipleEquals("1",2,"3",4) { }

您甚至可以混合和匹配对象:

{{1}}

答案 3 :(得分:2)

  

此外,我计划在这些字符串数量不详的情况下,   并且希望避免使用混乱的if()s嵌套的复杂for循环   他们内心。

我认为for循环不会那么复杂。

您当然可以通过尝试

来检查是否平等
xcopy "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cvtres.exe" "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\"

但是将所有内容与a.equals(b) b.equals(c) etc. 进行比较会得到相同的结果。如果一切都等于a,那么一切都是相等的。

a

这使for循环更简单。如果你不介意将a.equals(b) a.equals(c) etc. 与自身进行比较的开销,你可以简单地检查你的整个数组或集合(或其他)是否相等。

if也不会显得混乱。只要一对字符串不相等,就会从函数a开始。

答案 4 :(得分:2)

这可能是一个不寻常的想法,但这样的情况是一个小元编程可能会派上用场。

public static void nEquals(int nOverloads, PrintStream out) {
    if (nOverloads < 2)
        throw new IllegalArgumentException();

    for (int i = 2; i <= nOverloads; ++i) {
        out.println("public static boolean equals(");
        out.print("        Object obj0");

        for (int j = 1; j < i; ++j) {
            out.print(", Object obj" + j);
        }

        out.println(") {");
        out.print("    return obj0.equals(obj1)");

        for (int j = 2; j < i; ++j) {
            out.print(" && obj0.equals(obj" + j + ")");
        }

        out.println(";");
        out.println("}");
    }
}

nEquals(4, System.out);打印以下内容:

public static boolean equals(
        Object obj0, Object obj1) {
    return obj0.equals(obj1);
}
public static boolean equals(
        Object obj0, Object obj1, Object obj2) {
    return obj0.equals(obj1) && obj0.equals(obj2);
}
public static boolean equals(
        Object obj0, Object obj1, Object obj2, Object obj3) {
    return obj0.equals(obj1) && obj0.equals(obj2) && obj0.equals(obj3);
}

您可以根据需要生成任意数量的重载,不需要varargs。只需复制并粘贴到实用程序类即可。

if (Util.equals(a, b, c)) {
    doSomething();
}

对于这种简单的代码生成,误差范围很小。唯一的缺点是可维护性,因为如果有人确实需要修改它(例如更改null的处理,在我和你的例子中都被忽略),他们需要修改生成器并再次运行它。

答案 5 :(得分:1)

这样的事情怎么样:

boolean allEqual(List<String> elements) {
    if(elements.isEmpty() || elements.size() == 1) {
        return true;
    }
    String current = elements.get(0);
    if(current == null) {
        return false;
    }
    for(int i = 1; i < elements.size(); i++) {
        if(!current.equals(elements.get(i))) {
            return false;
        }
        current = elements.get(i);
    }
    return true;
}

不完全漂亮,但你只需要编写一次,它适用于任意数量的字符串。

答案 6 :(得分:-1)

另一种方法是使用String作为Comparable的实现。

public <T extends Comparable<T>> boolean equality(T... objects) {
    Arrays.sort(objects);
    return objects[0].compareTo(objects[objects.length - 1]) == 0;
}

<强>优点: 此解决方案适用于所有Comparable个对象。

缺点:如果所有值都等于N(太棒了!)比较,否则N logN最大值。此处还将为sort方法分配用于临时存储的内存,该方法将从非常小到N/2