开发者

Violating rule of reflexivity when overriding equals method

I have a doubt from the book Efective Java. The doubt is regarding equals method

reflexive rule violation. The book says the following:

"If you were to violate it and then add an instance of your class to a collection, the collection's contains method would almost certainly say that the collection did not contain the instance that you just added."

To test it I wrote an example class, but the contains method doesn't return false 开发者_StackOverflow中文版It returns true. Can anybody tell what is the problem?


I agree that the result of this program is indeed puzzling:

import java.util.*;

class Item {
    @Override
    public boolean equals(Object obj) {
        return false;   // not even equal to itself.
    }
}

class Test {
    public static void main(String[] args) {
        Collection<Item> items = new HashSet<Item>();
        Item i = new Item();
        items.add(i);
        System.out.println(items.contains(i));   // Prints true!
    }
}

The answer is that the contains implementation checks argument == object before doing argument.equals(object). The result from contains is true since item == item holds, even though item.equals(item) returns false.

Assuming equals follows its contract (is reflexive), this way of implementing contains is correct.


If you read the quote you posted carefully, the author includes the word "almost" :) It seems you stumbled across one of the few exceptions to the rule.


Other collections (ArrayList for instance) uses equals directly, and if you change from new HashSet<Item>() to new ArrayList<Item>() in the above program it prints false as expected.


Reflexive means x.equals(x) should return true

class Foo {
   int i;
   public boolean equals(Object obj) {
      return ((Foo) obj).i < this.i;
   }
}

this will return false. And when you put it into a list and call list.contains(foo) it will return false, because none of the elements in the list was equal to the one you passed. This is so because list.contains(..) iterates the elements and for each of them checks if (elem.equals(arg))

See the docs of Collection.contains(..)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜