Причина
Причины наблюдаемого поведения описаны в java .lang.Record
Для всех классов записей следующий инвариант должен содержать: если компонентами записи R являются c1, c2, ... cn, то если экземпляр записи копируется следующим образом:
R copy = new R(r.c1(), r.c2(), ..., r.cn()); then it must be the case that r.equals(copy).
Короче говоря, ваш класс CityRecord
теперь имеет реализация equals
(и хэш-кода), которая сравнивает два атрибута и гарантирует, что, если они равны, запись, состоящая из этих компонентов, также равна. В результате этой оценки два объекта записи с одинаковыми атрибутами будут сгруппированы вместе.
Следовательно, результат будет правильным, чтобы заключить / утверждать, что должно быть три таких ключа, причем один из них имеет id=2, name="two"
, подсчитанный дважды.
Немедленное исправление
An немедленным временным решением этой проблемы было бы создание собственной (ошибочной - причина объяснена позже) equals
реализации в вашем представлении записи. Это будет выглядеть так:
record CityRecord(Integer id, String name) {
// WARNING, BROKEN CODE
// Does not adhere to contract of `Record::equals`
@Override
public boolean equals(Object o) {
return this == o;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
}
Теперь, когда сравнение будет между двумя объектами, как при использовании существующего класса City
, ваши тесты будут работать нормально. Но вы должны обратить внимание на предостережение ниже, прежде чем использовать любое из этих средств.
Осторожно
Поскольку JEP-359 читает, Записи больше похожи на "носитель данных" и при выборе чтобы перенести существующие классы, вы должны знать о стандартных членах, которые автоматически получают запись .
При планировании миграции необходимо знать полные детали текущей реализации, например, в приведенном вами примере, когда вы группировали по City
, не должно быть причин иметь два города с одинаковыми id
и name
data должны быть перечислены по-разному. Они должны быть равны, это должны быть одинаковые данные после всех повторений дважды и, следовательно, правильные значения.
В этом случае ваша существующая реализация, если представляет данные модель может быть исправлена таким образом, чтобы она соответствовала record
, путем перезаписи реализации equals
, чтобы учесть сравнение отдельных атрибутов, в которых непосредственное средство защиты, указанное выше, противоречиво и его следует избегать.