在 Java 中检查三个或更多字符串的相等性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30560338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Checking equality of three or more Strings in Java
提问by Robert Krupp
I know this is a very basic question, but I am always trying to find ways to make my code a clean and concise as possible. Is there a way to compare the equality of three or more strings in a single if()
statement? I am currently using the &&
operator to progressively compare each string. However, as you could imagine, between long variable names and methods being called, these if()
statements get very cluttered very quickly. Additionally I am planning to have an unknown number of these Strings, and would like to avoid complex for
loops with cluttered if()
s nested inside of them. This is what my code currently looks like:
我知道这是一个非常基本的问题,但我一直在努力寻找使我的代码尽可能简洁明了的方法。有没有办法在单个if()
语句中比较三个或更多字符串的相等性?我目前正在使用&&
运算符逐步比较每个字符串。然而,正如您所想象的,在长变量名和被调用的方法之间,这些if()
语句很快就会变得非常混乱。此外,我计划使用未知数量的这些字符串,并希望避免复杂的for
循环,其中if()
嵌套有杂乱的s。这是我的代码目前的样子:
String a = new String("a");
String b = new String("b");
String c = new String("c");
if(a.equals(b) && b.equals(c)) {
doSomething();
}
Is there a way, or a collection of some sort that I can use that would allow me to compare these values more like this:
有没有一种方法或某种我可以使用的集合可以让我更像这样比较这些值:
if(a.equals(b).equals(c)) {
doSomething();
}
采纳答案by Timo
There is no simple way to chain your equals()
commands like this. In order to be able to chain them this way, equals()
would have to return a reference to the String itself. Then, however, it can't return a boolean value that represents the outcome of the comparison anymore.
没有equals()
像这样链接命令的简单方法。为了能够以这种方式链接它们,equals()
必须返回对 String 本身的引用。但是,它不能再返回表示比较结果的布尔值。
Also, I see it as not particularly problematicto compare three strings separately as in your first example. Make sure you keep your code well formatted, and it will remain easy to understand, even for longer variable names:
另外,我认为像第一个示例中那样分别比较三个字符串并不是特别成问题。确保你的代码格式良好,即使变量名更长,它也会很容易理解:
if(myValueAWithALongName.equals(myValueBWithALongName) &&
myValueBWithALongName.equals(myValueCWithALongName) &&
myValueCWithALongName.equals(myValueDWithALongName) &&
... ) {
Alternatively, you could use one of the other solutions proposed in this thread and wrap your values into a Collection and write a helper method. Note however that this might have a negative impact on memory usage, performance and possibly readablity.
或者,您可以使用该线程中提出的其他解决方案之一,并将您的值包装到一个集合中并编写一个辅助方法。但是请注意,这可能会对内存使用、性能和可读性产生负面影响。
On a side note, you should never create Strings using the Constructor new String()
. Simply assign the string literal directly to your variable:
附带说明一下,您永远不应该使用 Constructor 创建字符串new String()
。只需将字符串文字直接分配给您的变量:
String a = "a";
回答by niceguy
How about something like this:
这样的事情怎么样:
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;
}
Not exactly pretty, but you need to write it only once and it works for an arbitrary number of strings.
不是很漂亮,但你只需要写一次它就可以处理任意数量的字符串。
回答by Tagir Valeev
If you have several objects of the same type, it's a good idea to organize them in the data structure like array or list. So suppose you have a List
of String
objects:
如果您有多个相同类型的对象,最好将它们组织在数组或列表等数据结构中。因此,假设你有一个List
的String
对象:
List<String> strings = Arrays.asList("a", "b", "a", ...);
You want to know whether all the strings in the list equal to each other. This can be done in a number of methods. Probably the shortest one is:
您想知道列表中的所有字符串是否彼此相等。这可以通过多种方法来完成。可能最短的是:
if(new HashSet<>(strings).size() == 1) {
// all strings are equal
}
Longer, but more optimal solution is proposed by @niceguy. If you are using Java-8, you can also do this way:
@niceguy 提出了更长但更优化的解决方案。如果您使用的是 Java-8,您也可以这样做:
if(strings.stream().distinct().count() == 1) {
// all strings are equal
}
回答by Aliaksei Yatsau
One more way is to use String
as implementation of Comparable
.
另一种方法是使用String
as 的实现Comparable
。
public <T extends Comparable<T>> boolean equality(T... objects) {
Arrays.sort(objects);
return objects[0].compareTo(objects[objects.length - 1]) == 0;
}
Pros:This solution is universal for all Comparable
objects.
优点:此解决方案适用于所有Comparable
对象。
Cons: If all values equals that it'll be N
(great!) comparison otherwise N logN
max. Also here will be allocated memory for temporary storage for sort
method which will vary from very small to N/2
.
缺点:如果所有值都相等,它将是N
(很棒!)比较,否则N logN
最大。此处还将为sort
方法分配内存用于临时存储,方法从非常小到N/2
.
回答by CKing
There are different ways to approach this problem depending on the number of String
objects being compared.
根据String
比较对象的数量,有不同的方法来解决这个问题。
If you only have a few String
objects to be compared and you pretty much need to do this kind of comparison in one or two places in your application, you can wrap the code in a method inside the class that needs such a comparison so that the code becomes more readable :
如果您只有几个String
对象要比较,并且您几乎需要在应用程序中的一两个地方进行这种比较,您可以将代码包装在需要这种比较的类中的方法中,以便代码变得更具可读性:
public boolean isConditionSatisfied(String a,String b,String c) {
return Objects.equals(a,b) && Objects.equals(b,c);
}
The client code then be simplified and more readable :
然后客户端代码被简化且更具可读性:
if(isConditionSatisfied(a,b,c)) { //doSomething }
Note that Objects.equals
is an inbuilt method available since JDK 1.7. In comparison to the other answers, the use of Object.equals
safeguards you from a NullPointerExcsption
which in my opinion is an absolute necessity.
请注意,这Objects.equals
是自 JDK 1.7 以来可用的内置方法。与其他答案相比,我认为使用Object.equals
保护措施NullPointerExcsption
是绝对必要的。
If you find yourself needing this kind of a comparison quite often (and not only for String
objects) why look for a solution only for comparing String
objects? Why not find a generic solution that will work for any kind or number of objects?
如果您发现自己经常需要进行这种比较(不仅是针对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;
}
}
Ok so you want to compare 4 String
objects, why not :
好的,所以你想比较 4 个String
对象,为什么不:
if(ObjectUtils.multipleEquals("1","1","1","1") { }
But now you want to compare 5 Integer
objects, no problem :
但是现在要比较 5 个Integer
对象,没问题:
if(ObjectUtils.multipleEquals(1,2,3,4,5) { }
You can even mix and match objects :
您甚至可以混合和匹配对象:
if(ObjectUtils.multipleEquals("1",2,"3",4) { }
回答by null
Additionally I am planning to have an unknown number of these Strings, and would like to avoid complex for loops with cluttered if()s nested inside of them.
此外,我计划使用未知数量的这些字符串,并希望避免复杂的 for 循环,其中嵌套了杂乱的 if()。
I don't think that a for loop would be that complex.
我认为 for 循环不会那么复杂。
You can certainly check for equality by trying
您当然可以通过尝试检查相等性
a.equals(b)
b.equals(c)
etc.
But comparing everything to a
will have the same result. If everything is equal to a
, everything is equal to each other.
但是将所有内容进行比较a
将得到相同的结果。如果一切都等于a
,则一切都彼此相等。
a.equals(b)
a.equals(c)
etc.
This makes the for loop simpler. If you don't mind the overhead of comparing a
to itself you can simply check your entire array or collection (or whatever) against a for equality.
这使得 for 循环更简单。如果您不介意与a
自身进行比较的开销,您可以简单地根据 a 检查您的整个数组或集合(或其他任何内容)是否相等。
The if doesn't look cluttered either. return
from the function as soon as one pair of strings is not equal.
if 看起来也不杂乱。return
从函数中,只要一对字符串不相等。
回答by Radiodef
This may be an unusual idea, but situations like this are where a little metaprogramming may come in handy.
这可能是一个不寻常的想法,但在这种情况下,一些元编程可能会派上用场。
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);
prints the following:
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);
}
You can generate as many overloads as you want, no need for varargs. Just copy and paste to a utility class and you're done.
您可以根据需要生成任意数量的重载,无需可变参数。只需复制并粘贴到实用程序类即可完成。
if (Util.equals(a, b, c)) {
doSomething();
}
For such a simple code generation, the margin for error is small. The only downside is maintainability, because if somebody ever did need to tinker with it (such as to change the handling of null, which is ignored in both my and your examples), they need to modify the generator and run it again.
对于这样一个简单的代码生成,错误的余地很小。唯一的缺点是可维护性,因为如果有人确实需要修改它(例如更改 null 的处理,这在我和你的示例中都被忽略),他们需要修改生成器并再次运行它。