From: Roedy Green on 31 May 2010 23:56 On Mon, 31 May 2010 06:55:15 -0700 (PDT), laredotornado <laredotornado(a)zipmail.com> wrote, quoted or indirectly quoted someone who said : >he 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. Here is the code for put: public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } You can see it using equals, but only as a last resort. That is why it does not always call your equals method. -- Roedy Green Canadian Mind Products http://mindprod.com Have you ever noticed that any computer search in the movies, is always linear, with, for example, candidate fingerprints flashing up on the screen one after another? The public is still under the delusion that electronic files are microscopic filing cabinets made out of tiny wires or magnetic patches inside the computer. Most lay people are surprised that it is easy for a computer to file things simultaneously by a dozen different schemes, and that they can have any report printed in any number of different sorted orders. With physical files, they are limited to one ordering/access.
From: Robert Klemme on 1 Jun 2010 12:39 On 31.05.2010 21:58, Mike Schilling wrote: > Tom Anderson wrote: >> On Mon, 31 May 2010, Robert Klemme wrote: >> >>> On 31.05.2010 18:57, Tom Anderson wrote: >>>> On Mon, 31 May 2010, Lew wrote: >>>> >>>>> Tom Anderson wrote: >>>>>> if ((obj == null) || !(obj instanceof SearchResultHotels)) return >>>>>> false; >>>>> >>>>> The '(obj == null)' clause is superfluous. >>>> >>>> Good point. >>>> >>>> My brain, for some reason, has a hard time remembering that: >>>> >>>> SearchResultHotels x = (SearchResultHotels)null; >>>> >>>> is okay but: >>>> >>>> null instanceof SearchResultHotels >>>> >>>> is false. >>> >>> You just need to remember that null does not have a type. At least >>> that's what helped me to get this straight. :-) >> >> Yes, when i think about it, it's all perfectly clear. But i get it >> wrong when i'm not thinking about it. > > Me too. Especially since the usage > > if (x instanceof Type) > { > Type t = (Type)x; > ... > > is so common. The instanceof check (among other things) avoids a cast > failure, but the cast would work perfectly well if x were null. But then you'd get a NPE as soon as you try to invoke any method on the reference - so the idiom totally makes sense and the instanceof check avoids a cast failure *and* a NPE. Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Daniel Pitts on 1 Jun 2010 17:24 On 5/31/2010 11:18 AM, Lew wrote: > Lew wrote: >>> Always override 'equals()', 'hashCode()' and 'toString()' together or >>> not at all; keep them consistent with each other. If 'Foo' implements >>> 'Comparable<Foo>' then it must override those three, all consistent with >>> 'compareTo(Foo)'. > > Arne Vajhøj wrote: >> There are very good reasons to override equals and hashCode together. >> >> I can see many cases where overriding toString alone makes sense, >> because its main purpose is to make developer logging easier. And >> often you will want to log something without it having to be >> comparable. > > There's nothing in my advice to require loggable things to be Comparable. > > If you're logging information that identifies an instance, by definition > you have to provide a string representation of the identifying > attributes of the instance. If you aren't logging an instance's > identifying attributes, you don't use 'toString()' in the log message. > Ergo, 'toString()' has to include the identifying attributes of the > instance to be useful. > > The identifying attributes of the instance are precisely those that > figue in to 'equals()' and 'hashCode()', with the possible addition of > the object identifier. Ergo, 'toString()' must be consistent with > 'equals()' and 'hashCode()', in the sense that it must represent the > values of the attributes that figure in to those methods. > > Q.E.D. Except your premise of the purpose of toString is incorrect. toString needn't be consistent with equals or hashCode, as it needn't include any of the same set of information and still fulfill its contract. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Arved Sandstrom on 1 Jun 2010 17:47 Daniel Pitts wrote: > On 5/31/2010 11:18 AM, Lew wrote: >> Lew wrote: >>>> Always override 'equals()', 'hashCode()' and 'toString()' together or >>>> not at all; keep them consistent with each other. If 'Foo' implements >>>> 'Comparable<Foo>' then it must override those three, all consistent >>>> with >>>> 'compareTo(Foo)'. >> >> Arne Vajhøj wrote: >>> There are very good reasons to override equals and hashCode together. >>> >>> I can see many cases where overriding toString alone makes sense, >>> because its main purpose is to make developer logging easier. And >>> often you will want to log something without it having to be >>> comparable. >> >> There's nothing in my advice to require loggable things to be Comparable. >> >> If you're logging information that identifies an instance, by definition >> you have to provide a string representation of the identifying >> attributes of the instance. If you aren't logging an instance's >> identifying attributes, you don't use 'toString()' in the log message. >> Ergo, 'toString()' has to include the identifying attributes of the >> instance to be useful. >> >> The identifying attributes of the instance are precisely those that >> figue in to 'equals()' and 'hashCode()', with the possible addition of >> the object identifier. Ergo, 'toString()' must be consistent with >> 'equals()' and 'hashCode()', in the sense that it must represent the >> values of the attributes that figure in to those methods. >> >> Q.E.D. > Except your premise of the purpose of toString is incorrect. toString > needn't be consistent with equals or hashCode, as it needn't include any > of the same set of information and still fulfill its contract. From the Object.toString() Javadocs: "In general, the toString method returns a string that "textually represents" this object." [ embedded quotation in the original ] To me that supports what Lew said, that toString() ought to be _consistent_ with equals() and hashCode(). I can't think of a "textual representation" of an object that ignores the information that identifies it. AHS
From: Daniel Pitts on 1 Jun 2010 17:55
On 6/1/2010 2:47 PM, Arved Sandstrom wrote: > Daniel Pitts wrote: >> On 5/31/2010 11:18 AM, Lew wrote: >>> Lew wrote: >>>>> Always override 'equals()', 'hashCode()' and 'toString()' together or >>>>> not at all; keep them consistent with each other. If 'Foo' implements >>>>> 'Comparable<Foo>' then it must override those three, all consistent >>>>> with >>>>> 'compareTo(Foo)'. >>> >>> Arne Vajhøj wrote: >>>> There are very good reasons to override equals and hashCode together. >>>> >>>> I can see many cases where overriding toString alone makes sense, >>>> because its main purpose is to make developer logging easier. And >>>> often you will want to log something without it having to be >>>> comparable. >>> >>> There's nothing in my advice to require loggable things to be >>> Comparable. >>> >>> If you're logging information that identifies an instance, by definition >>> you have to provide a string representation of the identifying >>> attributes of the instance. If you aren't logging an instance's >>> identifying attributes, you don't use 'toString()' in the log message. >>> Ergo, 'toString()' has to include the identifying attributes of the >>> instance to be useful. >>> >>> The identifying attributes of the instance are precisely those that >>> figue in to 'equals()' and 'hashCode()', with the possible addition of >>> the object identifier. Ergo, 'toString()' must be consistent with >>> 'equals()' and 'hashCode()', in the sense that it must represent the >>> values of the attributes that figure in to those methods. >>> >>> Q.E.D. >> Except your premise of the purpose of toString is incorrect. toString >> needn't be consistent with equals or hashCode, as it needn't include >> any of the same set of information and still fulfill its contract. > > From the Object.toString() Javadocs: > > "In general, the toString method returns a string that "textually > represents" this object." > > [ embedded quotation in the original ] > > To me that supports what Lew said, that toString() ought to be > _consistent_ with equals() and hashCode(). I can't think of a "textual > representation" of an object that ignores the information that > identifies it. > > AHS Perhaps a "Timing" object, which has a toString() which returns time in ms/s/minutes/etc..., but is not a value type (eg, identity is important). The object is textually represented, but equals/hashCode are not relevant to the contents of the textual representation. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/> |