From: laredotornado on 31 May 2010 09:55 Hi, I'm using Java 6. The Javadocs suggest that Map uses containsKey, and hence an Object's equals method to determine if the object is already a key in the map. However, I'm noticing that when I define this equals method on an object I'm inserting as a key in my Map (a HashMap): public boolean equals(Object obj) { SearchResultHotels hotel = (SearchResultHotels) obj; boolean ret = obj != null && ((SearchResultHotels) obj).getId() == getId(); log.debug("\t comparing " + hotel.getName() + " to " + getName() + ":" + ret); return ret; } I never see my log statement printed out when I call "map.put". What am I missing? Thanks, - Dave
From: Tom Anderson on 31 May 2010 10:12 On Mon, 31 May 2010, laredotornado wrote: > I'm using Java 6. The Javadocs suggest that Map uses containsKey, Map can't use anything, because it's an interface. I will assume you are talking about HashMap. > and hence an Object's equals method to determine if the object is > already a key in the map. However, I'm noticing that when I define this > equals method on an object I'm inserting as a key in my Map (a HashMap): > > public boolean equals(Object obj) { > SearchResultHotels hotel = (SearchResultHotels) obj; An aside: if someone passes in an object which is not a SearchResultHotels, you need to return false; this will throw a ClassCastException, which is wrong. A common opening to equals implementations is: if (obj == this) return true; if ((obj == null) || !(obj instanceof SearchResultHotels)) return false; SearchResultHotels hotel = (SearchResultHotels)obj; Or code to that effect. > boolean ret = obj != null && ((SearchResultHotels) obj).getId() == getId(); > log.debug("\t comparing " + hotel.getName() + " to " + getName() + ":" + ret); > return ret; > } > > I never see my log statement printed out when I call "map.put". What > am I missing? You don't show anywhere near enough code to answer that. Post the code that makes the map and does the put. Assuming you're talking about a situation like: Map<SearchResultHotels, Object> m = new HashMap<SearchResultHotels, Object>(); SearchResultHotels hotel = somehowCreateSearchResultHotels(); m.put(hotel, "foo"); m.put(hotel, "bar"); Then i have a feeling HashMap checks for object identity (with ==) before calling equals, as a defensive optimisation in case the key objects have equals methods that do not efficiently detect identity. Try doing a put with a different but equal key: SearchResultHotels hotel = somehowCreateSearchResultHotels(); m.put(hotel, "foo"); SearchResultHotels equalHotel = somehowCreateSearchResultHotels(); m.put(equalHotel, "bar"); tom -- Is this chill-out music for dangerous loners?
From: Michal Kleczek on 31 May 2010 10:12 laredotornado wrote: > Hi, > > I'm using Java 6. The Javadocs suggest that Map uses containsKey, and > hence an Object's equals method to determine if the object is already > a key in the map. However, I'm noticing that when I define this > equals method on an object I'm inserting as a key in my Map (a > HashMap): > > public boolean equals(Object obj) { > SearchResultHotels hotel = (SearchResultHotels) obj; > boolean ret = obj != null && ((SearchResultHotels) obj).getId() == > getId(); > log.debug("\t comparing " + hotel.getName() + " to " + getName() + > ":" + ret); > return ret; > } > > I never see my log statement printed out when I call "map.put". What > am I missing? Probably int hashCode() (if a hashing map implementation is used). Or apropriate Comparable/Comparator implementation if you use a tree based map. -- Michal
From: Eric Sosman on 31 May 2010 10:21 On 5/31/2010 9:55 AM, laredotornado wrote: > Hi, > > I'm using Java 6. The Javadocs suggest that Map uses containsKey, and > hence an Object's equals method to determine if the object is already > a key in the map. Where do you find this suggestion? The Javadoc says that the Map interface *requires* that any class implementing it *provide* a containsKey() method, but doesn't say anything about how the class uses the method internally, or even whether it's used internally. > However, I'm noticing that when I define this > equals method on an object I'm inserting as a key in my Map (a > HashMap): > > public boolean equals(Object obj) { > SearchResultHotels hotel = (SearchResultHotels) obj; > boolean ret = obj != null&& ((SearchResultHotels) obj).getId() == > getId(); > log.debug("\t comparing " + hotel.getName() + " to " + getName() + > ":" + ret); > return ret; > } > > I never see my log statement printed out when I call "map.put". What > am I missing? One thing you're missing -- it's a side-issue to your question, but it's important anyhow -- is that this equals() method will throw ClassCastException if `obj' is a String or a JButton or anything other than a SearchResultHotels. Throwing CCE from equals() is a no-no; the method should simply return `false' meaning "The HoundOfTheBaskervilles object you handed me is unequal to `this'." To the question at hand, consider how a HashMap works: It computes the hashCode() of the key, and using that value it chooses a "bucket." If the bucket already holds a key/value pair with the same key, the new value replaces the old. If the bucket holds no pair with the given key, the new pair is added. And ... ... (drum roll, please) ... .... if the bucket is *empty*, how many times must HashMap call equals() to determine that the new key is not a duplicate? -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: laredotornado on 31 May 2010 10:27 On May 31, 9:12 am, Michal Kleczek <klek...(a)gmail.com> wrote: > laredotornado wrote: > > Hi, > > > I'm using Java 6. The Javadocs suggest that Map uses containsKey, and > > hence an Object's equals method to determine if the object is already > > a key in the map. However, I'm noticing that when I define this > > equals method on an object I'm inserting as a key in my Map (a > > HashMap): > > > public boolean equals(Object obj) { > > SearchResultHotels hotel = (SearchResultHotels) obj; > > boolean ret = obj != null && ((SearchResultHotels) obj).getId() == > > getId(); > > log.debug("\t comparing " + hotel.getName() + " to " + getName() + > > ":" + ret); > > return ret; > > } > > > I never see my log statement printed out when I call "map.put". What > > am I missing? > > Probably int hashCode() (if a hashing map implementation is used). Or > apropriate Comparable/Comparator implementation if you use a tree based map. > > -- > Michal When I defined a hashCode method, then everything was fine -- the HashMap object did not allow me to insert two keys that I considered the same. Per the other points about ClassCastExceptions in the equals method, I have implemented your suggestions. Thanks, -
|
Next
|
Last
Pages: 1 2 3 4 5 6 Prev: pattern question ? Next: How to troubleshoot whether Java is running out on someresource |