Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does HashSet 'add' method calls equals? [duplicate]

I did this test in a HashSet comparision and equals is not being called

I would like to consider equals when farAway=false (A function to check two point distances)

Full compilable code, you could test it, and tells why equals is not being called in this example.

public class TestClass{
     static class Posicion
    {
        private int x;
        private int y;

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Posicion other = (Posicion) obj;
            if ( farAway(this.x, other.x, this.y, other.y,5)){   
                return false;
            } 
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y;
            return hash;
        }

         Posicion(int x0, int y0) {
            x=x0;
            y=y0;
        }

        private boolean farAway(int x, int x0, int y, int y0, int i) {
            return false;
        }
    }

    public static void main(String[] args) {
        HashSet<Posicion> test=new HashSet<>();
        System.out.println("result:"+test.add(new Posicion(1,1)));
        System.out.println("result:"+test.add(new Posicion(1,2)));
    }
}

EDIT

-Is there a way to force HashSet add to call equals?

like image 532
Hernán Eche Avatar asked Jan 24 '13 15:01

Hernán Eche


People also ask

Does HashSet add duplicate values?

Duplicates: HashSet doesn't allow duplicate values. HashMap stores key, value pairs and it does not allow duplicate keys.

What happens when duplicate is added to HashSet?

HashSet doesn't allow duplicates. If you try to add a duplicate element in HashSet, the old value would be overwritten. HashSet allows null values, however if you insert more than one nulls, it would override the previous null value.

How does HashSet find duplicates in Java?

By using HashSet, a general-purpose Set implementation, we can find duplicates in O(n) time. All you need to do is iterate over an array using advanced for loop and insert every element into HashSet. Since it allows only unique elements, add() method will fail and return false when you try to add duplicates.

Does Set Add duplicates?

A Set is a Collection that cannot contain duplicate elements. It models the mathematical set abstraction. The Set interface contains only methods inherited from Collection and adds the restriction that duplicate elements are prohibited.


3 Answers

If you want equals() to be called always, just always return, say, 0 in hashCode(). This way all items have the same hash code and are compared purely with equals().

public int hashCode() {
  return 0;
}
like image 179
Sebastian Krysmanski Avatar answered Oct 01 '22 02:10

Sebastian Krysmanski


If the hash codes differ, there is no need to call equals() since it is guaranteed to return false.

This follows from the general contract on equals() and hashCode():

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

Right now your class is breaking that contract. You need to fix that.

like image 35
NPE Avatar answered Oct 01 '22 03:10

NPE


It sounds like HashSet isn't right for you. It sounds like you want a custom way of comparing two positions. Rather than saying "are two positions exactly equal?". Instead, you should look at using TreeSet, with a Comparator. This way, you can write a "IsWithinRangeComparator" and do your range checking there.

like image 20
David Lavender Avatar answered Oct 01 '22 01:10

David Lavender