我知道这是一个非常基本的问题,但我总是想方设法让我的代码尽可能简洁明了。有没有办法比较单个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"
}
}
}
}
}]
}
}
}
答案 0 :(得分:16)
没有简单的方法来链接这样的equals()
命令。为了能够以这种方式链接它们,equals()
必须返回对String本身的引用。然而,它不能再返回一个表示比较结果的布尔值。
此外,我将其视为并非特别有问题,以便在第一个示例中分别比较三个字符串。确保您的代码格式良好,即使对于较长的变量名称,它仍然易于理解:
if(myValueAWithALongName.equals(myValueBWithALongName) &&
myValueBWithALongName.equals(myValueCWithALongName) &&
myValueCWithALongName.equals(myValueDWithALongName) &&
... ) {
或者,您可以使用此线程中提出的其他解决方案之一,并将您的值包装到Collection中并编写辅助方法。但请注意,这可能会对内存使用情况,性能和可能的可读性产生负面影响。
另外,您不应该使用构造函数new String()
创建字符串。只需将字符串文字直接分配给您的变量:
String a = "a";
答案 1 :(得分:14)
如果您有多个相同类型的对象,最好将它们组织在数组或列表等数据结构中。假设您有List
个String
个对象:
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
。