Древовидная карта Григорианскалендаров


Я создал TreeMap из <GregorianCalendar, Integer> для хранения дат, в которых были введены високосные секунды GPS:

leapSecondsDict = new TreeMap<GregorianCalendar, Integer>();
GregorianCalendar calendar =
    new GregorianCalendar(TimeZone.getTimeZone("UTC"));

calendar.set(1981, GregorianCalendar.JUNE, 30, 23, 59, 59);
leapSecondsDict.put(calendar, 1);
calendar.set(1982, GregorianCalendar.JUNE, 30, 23, 59, 59);
leapSecondsDict.put(calendar, 2);
calendar.set(1983, GregorianCalendar.JUNE, 30, 23, 59, 59);
leapSecondsDict.put(calendar, 3);
Проблема в том, что каждый раз, когда я вызываю put, TreeMap содержит только последний вставленный элемент, и размер остается 1.

Почему это происходит? Я предполагаю, что при использовании Calendar в качестве ключа Ключ является идентификатором экземпляра класса, а не его значением, поэтому при вставке второго элемента в TreeMap я буду обновлять существующую запись тем же ключом, даже если этот ключ теперь это тот же класс с другим значением.

Верно ли мое предположение, или есть какая-то другая причина? Есть ли какой-нибудь более дальновидный способ достижения этого, чем создание нового Calendar для каждой записи?
2 2

2 ответа:

Метод set не создает новый метод Calendar, он все тот же, но с другим значением. Поэтому, когда вы добавляете его в Map , он просто обновляет значение как свой же ключ, вы всегда ссылаетесь на один и тот же объект. Вам нужно создать новый экземпляр для каждого из ключей.

Как Balduz комментирует:

Метод set не создает новый календарь, он все тот же, но с другим значением. Поэтому, когда вы добавляете его на карту, он просто обновляет значение как свой же ключ, вы всегда ссылаетесь на один и тот же объект. Вам нужно создать новый экземпляр для каждого из ключей.

Таким образом, вы должны создавать новый каждый раз, что-то вроде:

GregorianCalendar calendar1 = new GregorianCalendar(1981, GregorianCalendar.JUNE, 30, 23, 59, 59);
calendar1.setTimeZone(TimeZone.getTimeZone("UTC"));
leapSecondsDict.put(calendar1, 1);
GregorianCalendar calendar2 = new GregorianCalendar(1982, GregorianCalendar.JUNE, 30, 23, 59, 59);
calendar2.setTimeZone(TimeZone.getTimeZone("UTC"));
leapSecondsDict.put(calendar2, 2);
GregorianCalendar calendar3 = new GregorianCalendar(1983, GregorianCalendar.JUNE, 30, 23, 59, 59);
calendar3.setTimeZone(TimeZone.getTimeZone("UTC"));
leapSecondsDict.put(calendar3, 3);