8029909: Clarify equals/hashcode behavior for java.time types
Summary: Document the behavior of equals and hashcode in java.time.chrono date types
Reviewed-by: sherman, scolebourne
--- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java Fri Dec 20 13:06:23 2013 -0500
+++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java Fri Dec 20 13:06:32 2013 -0500
@@ -600,6 +600,48 @@
return getChronology().period(Math.toIntExact(years), months, days);
}
+ //-------------------------------------------------------------------------
+ /**
+ * Compares this date to another date, including the chronology.
+ * <p>
+ * Compares this {@code HijrahDate} with another ensuring that the date is the same.
+ * <p>
+ * Only objects of type {@code HijrahDate} are compared, other types return false.
+ * To compare the dates of two {@code TemporalAccessor} instances, including dates
+ * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
+ *
+ * @param obj the object to check, null returns false
+ * @return true if this is equal to the other date and the Chronologies are equal
+ */
+ @Override // override for performance
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof HijrahDate) {
+ HijrahDate otherDate = (HijrahDate) obj;
+ return prolepticYear == otherDate.prolepticYear
+ && this.monthOfYear == otherDate.monthOfYear
+ && this.dayOfMonth == otherDate.dayOfMonth
+ && getChronology().equals(otherDate.getChronology());
+ }
+ return false;
+ }
+
+ /**
+ * A hash code for this date.
+ *
+ * @return a suitable hash code based only on the Chronology and the date
+ */
+ @Override // override for performance
+ public int hashCode() {
+ int yearValue = prolepticYear;
+ int monthValue = monthOfYear;
+ int dayValue = dayOfMonth;
+ return getChronology().getId().hashCode() ^ (yearValue & 0xFFFFF800)
+ ^ ((yearValue << 11) + (monthValue << 6) + (dayValue));
+ }
+
//-----------------------------------------------------------------------
/**
* Defend against malicious streams.
--- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java Fri Dec 20 13:06:23 2013 -0500
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java Fri Dec 20 13:06:32 2013 -0500
@@ -671,6 +671,18 @@
}
//-------------------------------------------------------------------------
+ /**
+ * Compares this date to another date, including the chronology.
+ * <p>
+ * Compares this {@code JapaneseDate} with another ensuring that the date is the same.
+ * <p>
+ * Only objects of type {@code JapaneseDate} are compared, other types return false.
+ * To compare the dates of two {@code TemporalAccessor} instances, including dates
+ * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
+ *
+ * @param obj the object to check, null returns false
+ * @return true if this is equal to the other date
+ */
@Override // override for performance
public boolean equals(Object obj) {
if (this == obj) {
@@ -683,6 +695,11 @@
return false;
}
+ /**
+ * A hash code for this date.
+ *
+ * @return a suitable hash code based only on the Chronology and the date
+ */
@Override // override for performance
public int hashCode() {
return getChronology().getId().hashCode() ^ isoDate.hashCode();
--- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java Fri Dec 20 13:06:23 2013 -0500
+++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java Fri Dec 20 13:06:32 2013 -0500
@@ -433,6 +433,18 @@
}
//-------------------------------------------------------------------------
+ /**
+ * Compares this date to another date, including the chronology.
+ * <p>
+ * Compares this {@code MinguoDate} with another ensuring that the date is the same.
+ * <p>
+ * Only objects of type {@code MinguoDate} are compared, other types return false.
+ * To compare the dates of two {@code TemporalAccessor} instances, including dates
+ * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
+ *
+ * @param obj the object to check, null returns false
+ * @return true if this is equal to the other date
+ */
@Override // override for performance
public boolean equals(Object obj) {
if (this == obj) {
@@ -445,6 +457,11 @@
return false;
}
+ /**
+ * A hash code for this date.
+ *
+ * @return a suitable hash code based only on the Chronology and the date
+ */
@Override // override for performance
public int hashCode() {
return getChronology().getId().hashCode() ^ isoDate.hashCode();
--- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java Fri Dec 20 13:06:23 2013 -0500
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java Fri Dec 20 13:06:32 2013 -0500
@@ -433,6 +433,18 @@
}
//-------------------------------------------------------------------------
+ /**
+ * Compares this date to another date, including the chronology.
+ * <p>
+ * Compares this {@code ThaiBuddhistDate} with another ensuring that the date is the same.
+ * <p>
+ * Only objects of type {@code ThaiBuddhistDate} are compared, other types return false.
+ * To compare the dates of two {@code TemporalAccessor} instances, including dates
+ * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
+ *
+ * @param obj the object to check, null returns false
+ * @return true if this is equal to the other date
+ */
@Override // override for performance
public boolean equals(Object obj) {
if (this == obj) {
@@ -445,6 +457,11 @@
return false;
}
+ /**
+ * A hash code for this date.
+ *
+ * @return a suitable hash code based only on the Chronology and the date
+ */
@Override // override for performance
public int hashCode() {
return getChronology().getId().hashCode() ^ isoDate.hashCode();