Compare Two Objects With .Equals() and == Operator

Compare two objects with .equals() and == operator

== compares object references, it checks to see if the two operands point to the same object (not equivalent objects, the same object).

If you want to compare strings (to see if they contain the same characters), you need to compare the strings using equals.

In your case, if two instances of MyClass really are considered equal if the strings match, then:

public boolean equals(Object object2) {
return object2 instanceof MyClass && a.equals(((MyClass)object2).a);
}

...but usually if you are defining a class, there's more to equivalency than the equivalency of a single field (a in this case).


Side note: If you override equals, you almost always need to override hashCode. As it says in the equals JavaDoc:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

What is the difference between == and equals() in Java?

In general, the answer to your question is "yes", but...

  • .equals(...) will only compare what it is written to compare, no more, no less.
  • If a class does not override the equals method, then it defaults to the equals(Object o) method of the closest parent class that has overridden this method.
  • If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality.
  • Always remember to override hashCode if you override equals so as not to "break the contract". As per the API, the result returned from the hashCode() method for two objects must be the same if their equals methods show that they are equivalent. The converse is not necessarily true.

Comparing two objects with == operator

I am not sure why it changes when you change it from 10 to 1

I believe this is an implementation detail and you should not rely on it (will try to find something in the specs) but some positive single digit numbers are cached in int.ToString implementation for .NET Core. Here is excerpt from UInt32ToDecStr which is called internally by int.ToString:

// For single-digit values that are very common, especially 0 and 1, just return cached strings.
if (bufferLength == 1)
{
return s_singleDigitStringCache[value];
}

As for equality - please check:

  1. C# difference between == and Equals().
  2. String interning in .Net Framework. (compiler will intern string literals, so all of them will point to the same address in memory)
  3. Using type dynamic

UPD:

Was not able to find anything in specs, but next code behaves differently in .NET Framework and .NET 6 (former one prints 11 times False and the latter prints 10 times True and one False):

var dict = new Dictionary<int, string>()
{
{0, "0"},
{1, "1"},
{2, "2"},
{3, "3"},
{4, "4"},
{5, "5"},
{6, "6"},
{7, "7"},
{8, "8"},
{9, "9"},
{10, "10"},
};

foreach(var kvp in dict)
{
Console.WriteLine(object.ReferenceEquals(kvp.Key.ToString(), kvp.Value));
}

UPD2:

The caching was introduced for performance reasons by this PR and is mentioned in Performance Improvements in .NET Core 3.0 blogpost:

In some sizeable web applications, we found that a large number of strings on the managed heap were simple integral values like “0” and “1”. And since the fastest code is code you don’t need to execute at all, why bother allocating and formatting these small numbers over and over when we can instead just cache and reuse the results (effectively our own string interning pool)? That’s what PR dotnet/coreclr#18383 does, creating a small, specialized cache of the strings for “0” through “9”, and any time we now find ourselves formatting a single-digit integer primitive, we instead just grab the relevant string from this cache.

private int _digit = 4;

[Benchmark]
public string SingleDigitToString() => _digit.ToString();










































MethodToolchainMeanErrorStdDevRatioGen 0Gen 1Gen 2Allocated
SingleDigitToStringnetcoreapp2.117.72 ns0.3273 ns0.3061 ns1.000.015232 B
SingleDigitToStringnetcoreapp3.011.57 ns0.1750 ns0.1551 ns0.65

What happens when you compare two of the same type objects using ==, >, <, etc, in Java?

Very simply the arithmetic comparison operators == and != compare the object references, or memory addresses of the objects. >, and < and related operators can't be used with objects.

So ==, != is useful only if you want to determine whether two different variables point to the same object.

As an example, this is useful in an event handler: if you have one event handler tied to e.g. multiple buttons, you'll need to determine in the handler which button has been pressed. In this case, you can use ==.

Object comparison of the type that you're asking about is captured using methods like .equals, or special purpose methods like String.compareTo.

It's worth noting that the default Object.equals method is equivalent to ==: it compares object references; this is covered in the docs. Most classes built into Java override equals with their own implementation: for example, String overrides equals to compare the characters one at a time. To get a more specific/useful implementation of .equals for your own objects, you'll need to override .equals with a more specific implementation.

Comparing two objects names in an equals method

In your equals method, you are comparing this object's atomLetter to itself.

if (atomLetter == this.atomLetter){ 

Instead, you need to cast the obj argument to the Element class and compare its atomLetter to this.atomLetter

Element other = (Element) obj;
return this.atomLettet == other.atomLettet;

Of course, you'll likely want to test that the cast is possible before actually doing it, and say that the objects are not equal if they are of different classes. Also test for null. The javadoc for object.Equals() explains all if the requirements for a proper equals method.

Compare two objects with < or > operators in Java

You cannot do operator overloading in Java. This means you are not able to define custom behaviors for operators such as +, >, <, ==, etc. in your own classes.

As you already noted, implementing Comparable and using the compareTo() method is probably the way to go in this case.

Another option is to create a Comparator (see the docs), specially if it doesn't make sense for the class to implement Comparable or if you need to compare objects from the same class in different ways.

To improve the code readability you could use compareTo() together with custom methods that may look more natural. For example:

boolean isGreaterThan(MyObject<T> that) {
return this.compareTo(that) > 0;
}

boolean isLessThan(MyObject<T> that) {
return this.compareTo(that) < 0;
}

Then you could use them like this:

if (obj1.isGreaterThan(obj2)) {
// do something
}

How to compare two java objects

You need to provide your own implementation of equals() in MyClass.

@Override
public boolean equals(Object other) {
if (!(other instanceof MyClass)) {
return false;
}

MyClass that = (MyClass) other;

// Custom equality check here.
return this.field1.equals(that.field1)
&& this.field2.equals(that.field2);
}

You should also override hashCode() if there's any chance of your objects being used in a hash table. A reasonable implementation would be to combine the hash codes of the object's fields with something like:

@Override
public int hashCode() {
int hashCode = 1;

hashCode = hashCode * 37 + this.field1.hashCode();
hashCode = hashCode * 37 + this.field2.hashCode();

return hashCode;
}

See this question for more details on implementing a hash function.

Compare two objects by reference when equality operator is overridden

Operators can't be overridden - they can only be overloaded.

So the == operator in object.ReferenceEquals is still comparing references, or you could do the same thing yourself by casting one or both operands:

string x = "some value";
string y = new string(x.ToCharArray());
Console.WriteLine(x == y); // True
Console.WriteLine((object) x == (object) y); // False
Console.WriteLine(ReferenceEquals(x, y)); // False


Related Topics



Leave a reply



Submit