is
will return True
if two variables point to the same object, ==
if the objects referred to by the variables are equal.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
In your case, the second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work:
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
The same holds true for string literals:
>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
Please see this question as well.
==
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).
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 value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new 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")) // --> true
Objects.equals(null, "test") // --> false
Objects.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:
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
.
Similar examples can also be found in JLS 3.10.5-1.
Other Methods To Consider
String.equalsIgnoreCase() value equality that ignores case. Beware, however, that this method can have unexpected results in various locale-related cases, see this question.
String.contentEquals() compares the content of the String
with the content of any CharSequence
(available since Java 1.5). Saves you from having to turn your StringBuffer, etc into a String before doing the equality comparison, but leaves the null checking to you.
Best Answer
From Common Lisp: Equality Predicates
Here are some examples from the same page I linked to above: