HashCode и равно для Collections.unmodifiableCollection()

Класс Collections имеет ряд статических вспомогательных методов для представления представлений только для чтения различных типов коллекций, таких как unmodifiableSet(), unmodifiableList() и т.д. Для этих объектов просмотра hashCode() и equals() методы переадресации вызовов в базовую коллекцию... С одним нечетным исключением: unmodifiableCollection().

JavaDoc явно указывает:

Возвращаемая коллекция не передает хэш-код и равнодействует операциям с базой данных, но полагается на методы Object equals и hashCode. Это необходимо для сохранения контрактов этих операций в случае, если коллекция поддержки является набором или списком.

Мой вопрос: wtf это говорит о??? Если коллекция поддержки представляет собой набор или список, я ожидаю, что поведение будет соответствовать unmodifiableSet() и unmodifiableList(). Как это нарушит контракты hashCode/equals?

Ответ 1

Из JavaDoc для коллекции:

Общий контракт для метода Object.equals указывает, что равен должен быть симметричным (другими словами, a.равнения (b) тогда и только тогда, когда b.equals(а)). В контрактах для List.equals и Set.equals указывается, что списки равны только другим спискам и присваиваются другим наборам. Таким образом, custom equals метод для класса коллекции, который не реализует ни интерфейс List или Set должен возвращать false, когда эта коллекция по сравнению с любым списком или множеством. (По той же логике невозможно напишите класс, который правильно реализует как Set, так и List интерфейсы.)

An UnmodifiableList является UnmodifiableCollection, но в обратном случае это неверно - a UnmodifiableCollection, который обертывает List, не является UnmodifiableList. Поэтому, если вы сравниваете UnmodifiableCollection, который обертывает List a с UnmodifiableList, который обертывает тот же список a, обе оболочки не должны быть равны. Если вы просто перешли к обернутому списку, они будут равны.