Now I get to share in the embarassment, I'd missed the strings are supposed to be interned.
2006-08-13 Sven de Marothy <[EMAIL PROTECTED]> * java/util/Locale.java (hashcodeCache): New field. (hashCode): use the above field instead of the serialized one (writeObject): Removed method. (equals): Revert to previous method.
Index: java/util/Locale.java =================================================================== RCS file: /sources/classpath/classpath/java/util/Locale.java,v retrieving revision 1.34 diff -U3 -r1.34 Locale.java --- java/util/Locale.java 13 Aug 2006 00:20:11 -0000 1.34 +++ java/util/Locale.java 13 Aug 2006 01:19:00 -0000 @@ -188,11 +188,17 @@ private String variant; /** - * This is the cached hashcode. When writing to stream, we write -1. + * This is where the JDK caches its hashcode. This is is only here + * for serialization purposes. The actual cache is hashcodeCache * * @serial should be -1 in serial streams */ - private int hashcode; + private int hashcode = -1; + + /** + * This is the cached hashcode. + */ + private transient int hashcodeCache; /** * Array storing all available locales. @@ -324,7 +330,7 @@ this.language = language; this.country = country; this.variant = variant; - hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode(); + hashcodeCache = language.hashCode() ^ country.hashCode() ^ variant.hashCode(); } /** @@ -899,7 +905,7 @@ */ public int hashCode() { - return hashcode; + return hashcodeCache; } /** @@ -917,29 +923,9 @@ return false; Locale l = (Locale) obj; - return (language.equals( l.language ) - && country.equals( l.country ) - && variant.equals( l.variant ) ); - } - - /** - * Write the locale to an object stream. - * - * @param s the stream to write to - * @throws IOException if the write fails - * @serialData The first three fields are Strings representing language, - * country, and variant. The fourth field is a placeholder for - * the cached hashcode, but this is always written as -1, and - * recomputed when reading it back. - */ - private void writeObject(ObjectOutputStream s) - throws IOException - { - // Hashcode field is always written as -1. - int temp = hashcode; - hashcode = -1; - s.defaultWriteObject(); - hashcode = temp; + return (language == l.language + && country == l.country + && variant == l.variant); } /** @@ -954,7 +940,9 @@ throws IOException, ClassNotFoundException { s.defaultReadObject(); - // Recompute hashcode. - hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode(); + language = language.intern(); + country = country.intern(); + variant = variant.intern(); + hashcodeCache = language.hashCode() ^ country.hashCode() ^ variant.hashCode(); } } // class Locale