Question

I was doing a little research on the difference between the two, and I noticed that .equals seems to simply be more reliable than ==. Is there a reason to use == over .equals other than the (I'm assuming) speed increase?

I'm doing this research because I'm doing a little work with Java. Would there be a more important distinction in usage when you consider other languages, like C# or C++? If so, could you tell me why?

EDIT: Maybe I should clarify. When I said that .equals is more reliable, I meant that I can't think of a comparison that .equals wouldn't be appropriate for, but it's easy to come up with situations in which you should avoid ==. Can anyone provide me with a rather specific example of when you'd use ==, but not .equals?

Était-ce utile?

La solution 4

Yes, there is a time to use == instead of equals method. Typically the equality method checks the usual output of the class. For example string containing the word "cat" so when you use the equality method that is what it checks. However a class is much more than just a single field, but many fields as well as an address in memory. When using == on a class it literally checks if it is pointing to the same instance in memory. Only with primitive types does == do what you think it does.

Here is a really cool experiment to demonstrate...

String a = "123";
String b = "123";

The compiler optimizes the strings to the same address and so == will return true. However change the value of b at run-time EVEN TO 123 and == will return false because now they have a different address in memory because the virtual machine is not smart enough or it would not be efficient to do these kind of optimizations at run-time.

Scanner input = new Scanner(System.in);
b = input.nextLine();

Even if you enter 123 it will cause the == to return false because now it created a new spot in memory.

Autres conseils

There's a big difference when comparing String objects in Java. Using equals() will compare the contents of the strings and tell you the result. Using == will compare the objects and tell you if the variables reference the same object. If you use == then two strings that contain exactly the same characters will appear to be not-equal because they are different objects (ie, you could modify one and the other would stay unchanged). The use of == to compare String objects is a very common mistake. equals() is the correct way to compare String contents.

== checks for reference equality; .equals checks for value equality. So they're not really checking the same thing; == is testing whether two things are the same object, and .equals is checking whether or not they have the same value (which is why some operation has to be defined for .equals, and can be overridden).

I was doing a little research on the difference between the two, and I noticed that .equals seems to simply be more reliable than ==.

Then your research is inadequate and/or your understanding of what you have read is incorrect.

In reality, == and equals are testing different things.

  • obj == obj2 is testing whether obj and obj2 are the same object reference.

  • obj.equals(obj2) is testing whether obj and obj2 are equals according to obj's definition / notion of what equality means. This could be the same as the first case. But it could be something completely different. It is entirely dependent on how the equals method is implemented ... for obj. For instance it is common for the equals test to involve comparing the values of the fields of the respective objects.

To illustrate, if I use == to test a pair of strings, I am actually testing to see if they are the same String object. But if I use equals, I am actually testing to see if the respective String objects consist of the same characters in the same order. These are two different tests, and in a lot of cases they will give different answers.

Is there a reason to use == over .equals other than the (I'm assuming) speed increase?

Yes. They mean different things. So you should primarily be choosing between == and equals based on the intended meaning of the test ... in the context that you are doing it.

Can anyone provide me with a rather specific example of when you'd use ==, but not .equals?

It might happen in a case where you have mutable objects. Sometimes you might need to compare them "by value". Other times you need to know whether two objects are actually the same. The latter might happen when you are traversing a graph of these objects, and you need to know if you have "been here before".

The problem is that any example is going to be a little artificial ... in the sense that it could probably be implemented other ways that are (arguably) better.

Well, there are some primitive datatypes where .equals would not be supported because the datatype in question is technically not a class (such as primitive boolean or integer).

Aside from that, there are -- as you already figured out -- performance differences when using == compared with using .equals.

Having said that, the use of '==' instead of .equals is usually an error in Java, unless you are inside a .equals method. '==' checks for equality of the references (think: equality of the pointers, if you are coming from a C/C++ world), and .equals invokes an equals method with semantics defined by the developer of the class.

One example is IdentityHashMap, see API

This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values). In other words, in an IdentityHashMap, two keys k1 and k2 are considered equal if and only if (k1==k2). (In normal Map implementations (like HashMap) two keys k1 and k2 are considered equal if and only if (k1==null ? k2==null : k1.equals(k2)).)

.equals() isn't more reliable as far as I know. It just serves a very different yet commonly overlooked purpose. As mentioned above, .equals() compares values -- not references -- and is useful when comparing certain things such as strings. I would recommend using == instead of .equals(), unless you know that .equals() is explicitly required. This is not only because == is faster, but also because it is common practice*.

*I'm a little wary of calling it convention, but it's definitely common practice

As others have said, == compares references while .equals compares values. == is faster than .equals, but if more than one instance of an object can have the same value and you are comparing the values, you can't use == and expect it to be right. If the two objects are a different instance, but have the same value, == will return false.

That said, there are some immutable objects that implement "instance control".

They do this using a static factory method. The class will define a static Map of instances of all the objects of itself that have been created. The static factory method will instantiate an object with the parameters passed to it. But, before returning the object, it checks the Map to see if it has an object of the same value.

If it finds one that is equal, it returns the object in the Map that has the same value instead of the newly created object.

If it does not find an object that is equal, it adds the newly created object to the Map and returns the new object.

The advantage of this is that, for objects that implement instance control, it is safe to use == to check for value equality because there is no way that two objects with the same value will ever exist.

Effective Java discusses instance control in Chapter 2.

Guava has classes called Interners that make it trivial for a class that wants to implement instance control to do so by storing objects of itself in the Interner construct.

Immutable objects that implement instance control like this should indicate that they do in their documentation. If they do, you know it is safe to use == to check for value equality. But, for any immutable objects that do not implement instance control, you should always use .equals to check for value equality.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top