How is "identity" defined for Java objects?

I want to add custom type objects to Set. I have several identical values, i.e. They have the same values ​​for their public variables.

I do not need to add more than one instance of the same object to the set, but every time a new object is created, it is always added.

This is because the equals method for the Object class implements the most different possible equivalence relation for objects: "For any non-empty reference values ​​x and y, this method returns true if and only if x and y refer to the same object ( x == y is true).

Is it possible to override the equals method for this object to define it differently?

Thanks everyone for resolving the issue.

Continuity for Java objects is determined by overriding the Java equals () method.

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((uri == null) ? 0 : uri.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Resource)) return false; Resource other = (Resource) obj; if (uri == null) { if (other.uri != null) return false; } else if (!uri.equals(other.uri)) return false; return true; } 
+4
source share
8 answers

You must override the equals and hashCode methods for your custom type.

Be careful, but here you can get into all kinds of things: for example, if you have subtypes for your custom type, you may encounter other equality problems:

 class Point { final int x; final int y; public Point(int x, int y) { this.x= x; this.y = y; } @Override public boolean equals(Object o) { if (o == this) return true; //If objects equal, is OK if (o instanceof Point) { Point that = (Point)o; return (x == that.x) && y == that.y); } return false; } } class ColoredPoint extends Point { final Color color; ColoredPoint(int x, int y, Color color) { super(x, y); this.color = color } } Point p1 = new Point(1, 2); ColoredPoint cp1 = new ColoredPoint(1, 2, Color.BLUE); ColoredPoint cp1 = new ColoredPoint(1, 2, Color.RED); 

Thus, p1, cp1 and cp2 are equal. However, obviously, cp1 and cp2 are not equal. To compare ColoredPoint objects, you need to implement equal values ​​in ColoredPoint, but this violates the equality between p1 and cp1 or cp2.

Also, make sure your equals has the signature above. A common mistake is its definition as public equals(Point that)... , which is incorrect.

See http://www.artima.com/lejava/articles/equality.html for a full explanation of the rules for equals and hashCode

+2
source

You need to override the equals() and hashCode() methods to tell the HashSet what you consider equal.

If you are using TreeSet, you should implement Comparable instead.

+5
source

As SLaks said, you must override the equals() and hashCode() methods. When you override equals() , you consider values, for example:

 public class MyObject public int x; public int y; public boolean equals(Object obj) { return (obj instance of MyObject) && (obj.x==x && obj.y==y); } public int hashCode() { return (x+y)*31; } 

}

+2
source

You should definitely redefine equals and hashCode , as they are methods used by Java to determine the equality of objects. By default, all Objects are different.

For more information on implementation, see Joshua Bloch's Effective Java Book in this chapter .

+1
source

You can absolutely override equals () to compare meaningful fields in your class. However, there are some important things to keep in mind. From http://www.javapractices.com/topic/TopicAction.do?Id=17 :

- if you override equals, you must override hashCode.

-hashCode should generate equal values ​​for equal objects.

-equals and hashCode must depend on the same set of "meaningful" fields. You must use the same set of fields in both of these methods. You are not required to use all fields. For example, a computed field that depends on others should most likely be omitted using equals and hashCode.

This is mainly because the Set data structure is implemented as a hash set; it requires hashCode () to put the object in the base array and find it later, and it requires equals () to resolve hash collisions (i.e. multiple objects that have a hash value with the same value).

Here is a good reference on implementing hashCode (): http://www.javamex.com/tutorials/collections/hash_function_guidelines.shtml

[EDIT]

I would like the second bone to advise reading the chapter of Josh Bloch on this issue. This is a phenomenal book.

+1
source

Regarding

I have a feeling that my problem is that they are not equal, because they are different objects that have the same meaning.

The default implementation of equals does the most rigorous work - the documentation speaks of the most varied possible form of the equality test, which should verify the identity (i.e. two links refer to the same location in memory).

This is a form of equality, but it is not always the most useful. Usually you want to check that two objects have the same properties. This is a completely natural thing that you want to do and is unworthy of any longing.

+1
source

Add the Set functionality, check the hashcode () method, and if it returns true, it will call equal (). Each object has a different memory cell and the equals () of the Object class simply compares the bit of the memory cell to check for equality. Therefore, each object is added.

For this to work, you will need to add both the hashCode () method and equals () to your class, and they will compare class-specific attributes that, like you, create the same value.

0
source

As SLaks has already noted, overriding the equals() and hashcode() methods definitely makes sense. To make sure that the equals() method behaves the way you want, check in the method whether the member variables that you consider to distinguish two objects have the same set of values ​​or not.

0
source

Source: https://habr.com/ru/post/1342648/


All Articles