[英]How do I compare strings in Java?

I've been using the == operator in my program to compare all my strings so far.However, I ran into a bug, changed one of them into .equals() instead, and it fixed the bug.


Is == bad? When should it and should it not be used? What's the difference?

是= =坏?什么时候应该不应该使用它?有什么不同?

23 个解决方案


== tests for reference equality (whether they are the same object).


.equals() tests for value equality (whether they are logically "equal").


Objects.equals() checks for null before calling .equals() so you don't have to (available as of JDK7, also available in Guava).


String.contentEquals() compares the content of the String with the content of any CharSequence (available since Java 1.5).

String.contentEquals()将String的内容与任何CharSequence的内容(自Java 1.5以来可用)进行比较。

Consequently, if you want to test whether two strings have the same value you will probably want to use Objects.equals().


// These two have the same valuenew String("test").equals("test") // --> true // ... but they are not the same objectnew String("test") == "test" // --> false // ... neither are thesenew String("test") == new String("test") // --> false // ... but these are because literals are interned by // the compiler and thus refer to the same object"test" == "test" // --> true // ... string literals are concatenated by the compiler// and the results are interned."test" == "te" + "st" // --> true// ... but you should really just call Objects.equals()Objects.equals("test", new String("test")) // --> trueObjects.equals(null, "test") // --> falseObjects.equals(null, null) // --> true

You almost always want to use Objects.equals(). In the rare situation where you know you're dealing with interned strings, you can use ==.


From JLS 3.10.5. String Literals:

来自JLS 3.10.5。字符串文字:

Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.

此外,字符串文字始终引用类String的相同实例。这是因为字符串文字 - 或者更常见的是作为常量表达式(第15.28节)的值的字符串 - 被“实例化”以便使用String.intern方法共享唯一实例。

Similar examples can also be found in JLS 3.10.5-1.

类似的例子也可以在JLS 3.10.5-1中找到。


== tests object references, .equals() tests the string values.


Sometimes it looks as if == compares values, because Java does some behind-the-scenes stuff to make sure identical in-line strings are actually the same object.


For example:

String fooString1 = new String("foo");String fooString2 = new String("foo");// Evaluates to falsefooString1 == fooString2;// Evaluates to truefooString1.equals(fooString2);// Evaluates to true, because Java uses the same object"bar" == "bar";

But beware of nulls!


== handles null strings fine, but calling .equals() from a null string will cause an exception:


String nullString1 = null;String nullString2 = null;// Evaluates to trueSystem.out.print(nullString1 == nullString2);// Throws a NullPointerExceptionSystem.out.print(nullString1.equals(nullString2));

So if you know that fooString1 may be null, tell the reader that by writing


System.out.print(fooString1 != null && fooString1.equals("bar"));

The following is shorter, but it’s less obvious that it checks for null (from Java 7):

以下内容较短,但检查null(来自Java 7)不太明显:

System.out.print(Objects.equals(fooString1, "bar"));


== compares Object references.


.equals() compares String values.


Sometimes == gives illusions of comparing String values, as in following cases:


String a="Test";String b="Test";if(a==b) ===> true

This is because when you create any String literal, the JVM first searches for that literal in the String pool, and if it finds a match, that same reference will be given to the new String. Because of this, we get:


(a==b) ===> true

(a == b)===>是的

                       String Pool     b -----------------> "test" <-----------------a

However, == fails in the following case:


String a="test";String b=new String("test");if (a==b) ===> false

In this case for new String("test") the statement new String will be created on the heap, and that reference will be given to b, so b will be given a reference on the heap, not in String pool.

在这种情况下,对于新的String(“test”),将在堆上创建语句new String,并且该引用将被赋予b,因此b将在堆上给出引用,而不是在String池中。

Now a is pointing to a String in the String pool while b is pointing to a String on the heap. Because of that we get:


if(a==b) ===> false.

if(a == b)===> false。

                String Pool     "test" <-------------------- a                   Heap     "test" <-------------------- b

While .equals() always compares a value of String so it gives true in both cases:


String a="Test";String b="Test";if(a.equals(b)) ===> trueString a="test";String b=new String("test");if(a.equals(b)) ===> true

So using .equals() is always better.



The == operator checks to see if the two strings are exactly the same object.


The .equals() method will check if the two strings have the same value.



Strings in Java are immutable. That means whenever you try to change/modify the string you get a new instance. You cannot change the original string. This has been done so that these string instances can be cached. A typical program contains a lot of string references and caching these instances can decrease the memory footprint and increase the performance of the program.


When using == operator for string comparison you are not comparing the contents of the string, but are actually comparing the memory address. If they are both equal it will return true and false otherwise. Whereas equals in string compares the string contents.


So the question is if all the strings are cached in the system, how come == returns false whereas equals return true? Well, this is possible. If you make a new string like String str = new String("Testing") you end up creating a new string in the cache even if the cache already contains a string having the same content. In short "MyString" == new String("MyString") will always return false.

所以问题是如果所有字符串都缓存在系统中,怎么来==返回false而equals返回true?嗯,这是可能的。如果你创建一个像String str = new String(“Testing”)这样的新字符串,你最终会在缓存中创建一个新字符串,即使缓存已经包含一个具有相同内容的字符串。简而言之,“MyString”== new String(“MyString”)将始终返回false。

Java also talks about the function intern() that can be used on a string to make it part of the cache so "MyString" == new String("MyString").intern() will return true.

Java还讨论了函数intern(),它可以在字符串上使用,使其成为缓存的一部分,因此“MyString”== new String(“MyString”)。intern()将返回true。

Note: == operator is much faster than equals just because you are comparing two memory addresses, but you need to be sure that the code isn't creating new String instances in the code. Otherwise you will encounter bugs.



String a = new String("foo");String b = new String("foo");System.out.println(a == b); // prints falseSystem.out.println(a.equals(b)); // prints true

Make sure you understand why. It's because the == comparison only compares references; the equals() method does a character-by-character comparison of the contents.

确保你理解为什么。这是因为==比较只比较参考; equals()方法对内容进行逐字符比较。

When you call new for a and b, each one gets a new reference that points to the "foo" in the string table. The references are different, but the content is the same.



Yea, it's bad...


== means that your two string references are exactly the same object. You may have heard that this is the case because Java keeps sort of a literal table (which it does), but that is not always the case. Some strings are loaded in different ways, constructed from other strings, etc., so you must never assume that two identical strings are stored in the same location.


Equals does the real comparison for you.



Yes, == is bad for comparing Strings (any objects really, unless you know they're canonical). == just compares object references. .equals() tests for equality. For Strings, often they'll be the same but as you've discovered, that's not guaranteed always.

是的,==不好比较字符串(任何对象真的,除非你知道它们是规范的)。 ==只是比较对象引用。 .equals()测试相等性。对于Strings来说,它们通常都是相同的,但正如你所发现的那样,总是不能保证。


Java have a String pool under which Java manages the memory allocation for the String objects. See String Pools in Java


When you check (compare) two objects using the == operator it compares the address equality into the string-pool. If the two String objects have the same address references then it returns true, otherwise false. But if you want to compare the contents of two String objects then you must override the equals method.


equals is actually the method of the Object class, but it is Overridden into the String class and a new definition is given which compares the contents of object.


Example:    stringObjectOne.equals(stringObjectTwo);

But mind it respects the case of String. If you want case insensitive compare then you must go for the equalsIgnoreCase method of the String class.


Let's See:

String one   = "HELLO"; String two   = "HELLO"; String three = new String("HELLO"); String four  = "hello"; one == two;   // TRUEone == three; // FALSEone == four;  // FALSEone.equals(two);            // TRUEone.equals(three);          // TRUEone.equals(four);           // FALSEone.equalsIgnoreCase(four); // TRUE


== compares object references in Java, and that is no exception for String objects.


For comparing the actual contents of objects (including String), one must use the equals method.


If a comparison of two String objects using == turns out to be true, that is because the String objects were interned, and the Java Virtual Machine is having multiple references point to the same instance of String. One should not expect that comparing one String object containing the same contents as another String object using == to evaluate as true.



I agree with the answer from zacherates.


But what you can do is to call intern() on your non-literal strings.


From zacherates example:


// ... but they are not the same objectnew String("test") == "test" ==> false 

If you intern the non-literal String equality is true


new String("test").intern() == "test" ==> true 


.equals() compares the data in a class (assuming the function is implemented).== compares pointer locations (location of the object in memory).


== returns true if both objects (NOT TALKING ABOUT PRIMITIVES) point to the SAME object instance..equals() returns true if the two objects contain the same data equals() Versus == in Java

==如果两个对象(不与基元相关)指向SAME对象实例,则返回true。如果两个对象包含相同的数据,则equals()返回true等于()Versus ==在Java中

That may help you.



== performs a reference equality check, whether the 2 objects (strings in this case) refer to the same object in the memory.


The equals() method will check whether the contents or the states of 2 objects are the same.


Obviously == is faster, but will (might) give false results in many cases if you just want to tell if 2 Strings hold the same text.


Definitely the use of equals() method is recommended.


Don't worry about the performance. Some things to encourage using String.equals():


  1. Implementation of String.equals() first checks for reference equality (using ==), and if the 2 strings are the same by reference, no further calculation is performed!
  2. String.equals()的实现首先检查引用相等性(使用==),如果2个字符串通过引用相同,则不执行进一步的计算!

  3. If the 2 string references are not the same, String.equals() will next check the lengths of the strings. This is also a fast operation because the String class stores the length of the string, no need to count the characters or code points. If the lengths differ, no further check is performed, we know they cannot be equal.
  4. 如果2个字符串引用不相同,String.equals()将接下来检查字符串的长度。这也是一个快速操作,因为String类存储字符串的长度,不需要计算字符或代码点。如果长度不同,不再进行进一步检查,我们知道它们不能相等。

  5. Only if we got this far will the contents of the 2 strings be actually compared, and this will be a short-hand comparison: not all the characters will be compared, if we find a mismatching character (at the same position in the 2 strings), no further characters will be checked.
  6. 只有当我们到达这一点时才会实际比较2个字符串的内容,这将是一个简短的比较:如果我们找到一个不匹配的字符(在2个字符串中的相同位置),不会比较所有字符),不会检查其他字符。

When all is said and done, even if we have guarantee that the strings are interns, using the equals() method is still not that overhead that one might think, definitely the recommended way. If you want efficient reference check, then use enums where it is guaranteed by the language specification and implementation that the same enum value will be the same object (by reference).



If you're like me, when I first started using Java, I wanted to use the "==" operator to test whether two String instances were equal, but for better or worse, that's not the correct way to do it in Java.


In this tutorial I'll demonstrate several different ways to correctly compare Java strings, starting with the approach I use most of the time. At the end of this Java String comparison tutorial I'll also discuss why the "==" operator doesn't work when comparing Java strings.

在本教程中,我将演示几种不同的方法来正确比较Java字符串,从我大多数时候使用的方法开始。在Java String比较教程的最后,我还将讨论为什么“==”运算符在比较Java字符串时不起作用。

Option 1: Java String comparison with the equals methodMost of the time (maybe 95% of the time) I compare strings with the equals method of the Java String class, like this:

选项1:Java字符串与equals方法的比较大部分时间(可能是95%的时间)我将字符串与Java String类的equals方法进行比较,如下所示:

if (string1.equals(string2))

This String equals method looks at the two Java strings, and if they contain the exact same string of characters, they are considered equal.

这个String equals方法查看两个Java字符串,如果它们包含完全相同的字符串,则它们被认为是相等的。

Taking a look at a quick String comparison example with the equals method, if the following test were run, the two strings would not be considered equal because the characters are not the exactly the same (the case of the characters is different):


String string1 = "foo";String string2 = "FOO";if (string1.equals(string2)){    // this line will not print because the    // java string equals method returns false:    System.out.println("The two strings are the same.")}

But, when the two strings contain the exact same string of characters, the equals method will return true, as in this example:


String string1 = "foo";String string2 = "foo";// test for equality with the java string equals methodif (string1.equals(string2)){    // this line WILL print    System.out.println("The two strings are the same.")}

Option 2: String comparison with the equalsIgnoreCase method


In some string comparison tests you'll want to ignore whether the strings are uppercase or lowercase. When you want to test your strings for equality in this case-insensitive manner, use the equalsIgnoreCase method of the String class, like this:


String string1 = "foo";String string2 = "FOO"; // java string compare while ignoring case if (string1.equalsIgnoreCase(string2)) {     // this line WILL print     System.out.println("Ignoring case, the two strings are the same.") }

Option 3: Java String comparison with the compareTo method

选项3:使用compareTo方法进行Java String比较

There is also a third, less common way to compare Java strings, and that's with the String class compareTo method. If the two strings are exactly the same, the compareTo method will return a value of 0 (zero). Here's a quick example of what this String comparison approach looks like:


String string1 = "foo bar";String string2 = "foo bar";// java string compare exampleif (string1.compareTo(string2) == 0){    // this line WILL print    System.out.println("The two strings are the same.")}

While I'm writing about this concept of equality in Java, it's important to note that the Java language includes an equals method in the base Java Object class. Whenever you're creating your own objects and you want to provide a means to see if two instances of your object are "equal", you should override (and implement) this equals method in your class (in the same way the Java language provides this equality/comparison behavior in the String equals method).

虽然我在Java中写这个关于平等的概念,但重要的是要注意Java语言在基础Java Object类中包含equals方法。每当您创建自己的对象并且想要提供一种方法来查看对象的两个实例是否“相等”时,您应该在类中覆盖(并实现)此equals方法(与Java语言提供的方式相同) String equals方法中的这种相等/比较行为)。

You may want to have a look at this ==, .equals(), compareTo(), and compare()




public float simpleSimilarity(String u, String v) {    String[] a = u.split(" ");    String[] b = v.split(" ");    long correct = 0;    int minLen = Math.min(a.length, b.length);    for (int i = 0; i < minLen; i++) {        String aa = a[i];        String bb = b[i];        int minWordLength = Math.min(aa.length(), bb.length());        for (int j = 0; j < minWordLength; j++) {            if (aa.charAt(j) == bb.charAt(j)) {                correct++;            }        }    }    return (float) (((double) correct) / Math.max(u.length(), v.length()));}


String a = "This is the first string.";String b = "this is not 1st string!";// for exact string comparison, use .equalsboolean exact = a.equals(b);// For similarity check, there are libraries for this// Here I'll try a simple example I wrotefloat similarity = simple_similarity(a,b);


The == operator check if the two references point to the same object or not. .equals() check for the actual string content (value).

==运算符检查两个引用是否指向同一对象。 .equals()检查实际的字符串内容(值)。

Note that the .equals() method belongs to class Object (super class of all classes). You need to override it as per you class requirement, but for String it is already implemented, and it checks whether two strings have the same value or not.


  • Case 1

    String s1 = "Stack Overflow";String s2 = "Stack Overflow";s1 == s2;      //trues1.equals(s2); //true

    Reason: String literals created without null are stored in the String pool in the permgen area of heap. So both s1 and s2 point to same object in the pool.


  • Case 2

    String s1 = new String("Stack Overflow");String s2 = new String("Stack Overflow");s1 == s2;      //falses1.equals(s2); //true

    Reason: If you create a String object using the new keyword a separate space is allocated to it on the heap.



== compares the reference value of objects whereas the equals() method present in the java.lang.String class compares the contents of the String object (to another object).



I think that when you define a String you define an object. So you need to use .equals(). When you use primitive data types you use == but with String (and any object) you must use .equals().



If the equals() method is present in the java.lang.Object class, and it is expected to check for the equivalence of the state of objects! That means, the contents of the objects. Whereas the == operator is expected to check the actual object instances are same or not.



Consider two different reference variables, str1 and str2:


str1 = new String("abc");str2 = new String("abc");

If you use the equals()



You will get the output as TRUE if you use ==.


System.out.println((str1==str2) ? "TRUE" : "FALSE");

Now you will get the FALSE as output, because both str1 and str2 are pointing to two different objects even though both of them share the same string content. It is because of new String() a new object is created every time.



Operator == is always meant for object reference comparison, whereas the String class .equals() method is overridden for content comparison:

Operator ==总是用于对象引用比较,而String类.equals()方法被覆盖用于内容比较:

String s1 = new String("abc");String s2 = new String("abc");System.out.println(s1 == s2); // It prints false (reference comparison)System.out.println(s1.equals(s2)); // It prints true (content comparison)


All objects are guaranteed to have a .equals() method since Object contains a method, .equals(), that returns a boolean. It is the subclass' job to override this method if a further defining definition is required. Without it (i.e. using ==) only memory addresses are checked between two objects for equality. String overrides this .equals() method and instead of using the memory address it returns the comparison of strings at the character level for equality.

保证所有对象都有.equals()方法,因为Object包含一个返回布尔值的方法.equals()。如果需要进一步的定义定义,则覆盖此方法是子类的工作。没有它(即使用==),仅在两个对象之间检查存储器地址是否相等。 String会覆盖此.equals()方法,而不是使用内存地址,它会返回字符级别的字符串比较以获得相等性。

A key note is that strings are stored in one lump pool so once a string is created it is forever stored in a program at the same address. Strings do not change, they are immutable. This is why it is a bad idea to use regular string concatenation if you have a serious of amount of string processing to do. Instead you would use the StringBuilder classes provided. Remember the pointers to this string can change and if you were interested to see if two pointers were the same == would be a fine way to go. Strings themselves do not.



You can also use the compareTo() method to compare two Strings. If the compareTo result is 0, then the two strings are equal, otherwise the strings being compared are not equal.


The == compares the references and does not compare the actual strings. If you did create every string using new String(somestring).intern() then you can use the == operator to compare two strings, otherwise equals() or compareTo methods can only be used.



In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.


The Java String class actually overrides the default equals() implementation in the Object class – and it overrides the method so that it checks only the values of the strings, not their locations in memory. This means that if you call the equals() method to compare 2 String objects, then as long as the actual sequence of characters is equal, both objects are considered equal.

Java String类实际上覆盖了Object类中的默认equals()实现 - 它覆盖了该方法,因此它只检查字符串的值,而不是它们在内存中的位置。这意味着如果调用equals()方法来比较2个String对象,那么只要实际的字符序列相等,两个对象就被认为是相等的。

The == operator checks if the two strings are exactly the same object.


The .equals() method check if the two strings have the same value.




粤ICP备14056181号  © 2014-2021 ITdaan.com