diff --git a/src/share/classes/java/text/DateFormatSymbols.java b/src/share/classes/java/text/DateFormatSymbols.java index 3e701b13799004a4a166353b0099247181e2c93f..ee688abd9b652ed61f25b6c89a990c263b04c8ea 100644 --- a/src/share/classes/java/text/DateFormatSymbols.java +++ b/src/share/classes/java/text/DateFormatSymbols.java @@ -45,6 +45,7 @@ import java.lang.ref.SoftReference; import java.text.spi.DateFormatSymbolsProvider; import java.util.Arrays; import java.util.Locale; +import java.util.Objects; import java.util.ResourceBundle; import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; @@ -366,6 +367,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ public void setEras(String[] newEras) { eras = Arrays.copyOf(newEras, newEras.length); + cachedHashCode = 0; } /** @@ -393,6 +395,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ public void setMonths(String[] newMonths) { months = Arrays.copyOf(newMonths, newMonths.length); + cachedHashCode = 0; } /** @@ -420,6 +423,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ public void setShortMonths(String[] newShortMonths) { shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length); + cachedHashCode = 0; } /** @@ -439,6 +443,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ public void setWeekdays(String[] newWeekdays) { weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length); + cachedHashCode = 0; } /** @@ -458,6 +463,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ public void setShortWeekdays(String[] newShortWeekdays) { shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length); + cachedHashCode = 0; } /** @@ -474,6 +480,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ public void setAmPmStrings(String[] newAmpms) { ampms = Arrays.copyOf(newAmpms, newAmpms.length); + cachedHashCode = 0; } /** @@ -558,6 +565,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { } zoneStrings = aCopy; isZoneStringsSet = true; + cachedHashCode = 0; } /** @@ -576,6 +584,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { public void setLocalPatternChars(String newLocalPatternChars) { // Call toString() to throw an NPE in case the argument is null localPatternChars = newLocalPatternChars.toString(); + cachedHashCode = 0; } /** @@ -597,12 +606,23 @@ public class DateFormatSymbols implements Serializable, Cloneable { * Override hashCode. * Generates a hash code for the DateFormatSymbols object. */ + @Override public int hashCode() { - int hashcode = 0; - String[][] zoneStrings = getZoneStringsWrapper(); - for (int index = 0; index < zoneStrings[0].length; ++index) - hashcode ^= zoneStrings[0][index].hashCode(); - return hashcode; + int hashCode = cachedHashCode; + if (hashCode == 0) { + hashCode = 5; + hashCode = 11 * hashCode + Arrays.hashCode(eras); + hashCode = 11 * hashCode + Arrays.hashCode(months); + hashCode = 11 * hashCode + Arrays.hashCode(shortMonths); + hashCode = 11 * hashCode + Arrays.hashCode(weekdays); + hashCode = 11 * hashCode + Arrays.hashCode(shortWeekdays); + hashCode = 11 * hashCode + Arrays.hashCode(ampms); + hashCode = 11 * hashCode + Arrays.deepHashCode(getZoneStringsWrapper()); + hashCode = 11 * hashCode + Objects.hashCode(localPatternChars); + cachedHashCode = hashCode; + } + + return hashCode; } /** @@ -641,6 +661,11 @@ public class DateFormatSymbols implements Serializable, Cloneable { private transient int lastZoneIndex = 0; + /** + * Cached hash code + */ + transient volatile int cachedHashCode = 0; + private void initializeData(Locale desiredLocale) { locale = desiredLocale; @@ -782,6 +807,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { dst.zoneStrings = null; } dst.localPatternChars = src.localPatternChars; + dst.cachedHashCode = 0; } /** diff --git a/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java b/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java index 20547219f53a20a633d799a8f3ce9b65c1d3c272..44d537b25ca32e4f2b333e6b3e642100a7f26726 100644 --- a/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java +++ b/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java @@ -44,6 +44,7 @@ public class DateFormatSymbolsProviderTest extends ProviderTest { DateFormatSymbolsProviderTest() { availableLocalesTest(); objectValidityTest(); + hashCodeTest(); } void availableLocalesTest() { @@ -124,4 +125,17 @@ public class DateFormatSymbolsProviderTest extends ProviderTest { } } } + + // Bug 7200341. + void hashCodeTest() { + for (Locale target: availloc) { + // look for provider's object + DateFormatSymbols dfs = DateFormatSymbols.getInstance(target); + if (dfs.getClass().getSimpleName().equals("FooDateFormatSymbols")) { + // call its hashCode(). success if no ArrayIndexOutOfBoundsException is thrown. + dfs.hashCode(); + break; + } + } + } } diff --git a/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.sh b/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.sh index 22c97d0a1ad4e0e59ab4ea30475471ab1764be77..24129cd81d7f1b03869d70608352015edc7c492c 100644 --- a/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.sh +++ b/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.sh @@ -23,6 +23,6 @@ #!/bin/sh # # @test -# @bug 4052440 +# @bug 4052440 7200341 # @summary DateFormatSymbolsProvider tests # @run shell ExecTest.sh foo DateFormatSymbolsProviderTest true diff --git a/test/java/util/PluggableLocale/fooprovider.jar b/test/java/util/PluggableLocale/fooprovider.jar index c1b5723f9b95dad064ed0393dd878cd7d82f3c51..125dbe17756199ab64388fa372f656af7e74440d 100644 Binary files a/test/java/util/PluggableLocale/fooprovider.jar and b/test/java/util/PluggableLocale/fooprovider.jar differ diff --git a/test/java/util/PluggableLocale/providersrc/DateFormatSymbolsProviderImpl.java b/test/java/util/PluggableLocale/providersrc/DateFormatSymbolsProviderImpl.java index 34a201afb87130a06d8b5c26c81130067c7a59d5..5c96fb28f88b689418c2c5b2c3cb310ecf5fef14 100644 --- a/test/java/util/PluggableLocale/providersrc/DateFormatSymbolsProviderImpl.java +++ b/test/java/util/PluggableLocale/providersrc/DateFormatSymbolsProviderImpl.java @@ -221,5 +221,10 @@ public class DateFormatSymbolsProviderImpl extends DateFormatSymbolsProvider { public void setAmPmStrings(String[] newAmpms) { ampms = newAmpms; } + + @Override + public String[][] getZoneStrings() { + return new String[0][0]; + } } }