Я тут почитал побольше про проблемы возникающие при переопределении equals, и у меня возникла крамольная мысля: а не сломан ли equals "by-design"? Ведь если отношения возникающие благодаря equals предполагают взаимозаменяемость объектов в пределах некоторого множества "эквивалентных" объектов, то оказывается невозможным не сломать и эту взаимозаменяемость, и LSP (принцип подстановки Барбары Лисков) одновременно. Поскольку LSP предполагает отношения наследования, то если экземпляры двух разных типов-наследников, одного родительского типа, реализующих различные интерфейсы, оказываются эквивалентны в целях соблюдения LSP, они оказываются не взаимозаменяемы, поскольку их интерфейсы не совпадают (например тот же RandomAccess, в случае ArrayList и LinkedList). Если же соблюдать принцип взаимозаменяемости, то ломается LSP, поскольку экземпляры не взаимозаменяемых типов-наследников не смогут быть эквивалентны, даже если спецификация родительского класса предполагает обратное (например спецификация equals интерфейса List). Кроме того, если класс реализует два различных интерфейса, каждый из которых предлагает свою спецификацию метода equals, то как быть в этом случае? При этом можно вспомнить ещё и про то, что даже среди объектов одного и того же класса, могут быть определены различные вариации отношения эквивалентности (например автомобили одной модели могут иметь одинаковую цену, но различаться по цвету, или набору дефолтных опций), а реализация equals предполагает выбор только одной из этих вариаций. Компараторы, в последнем случае, не помогут, так как:
  1. Для компараторов рекомендуется не противоречить equals. К примеру, TreeSet реализует Set, но ориентируется на значения возвращаемые компаратором. Если равенство определённое компаратором не соответствует equals, то, при добавлении объектов, LSP летит к чертям.
  2. Компараторы предназначены для определения отношений не эквивалентности, но строгого порядка. Поскольку существуют множества элементов, над которыми не определены отношения порядка, но определены отношения эквивалентности, то компараторы не слишком подходят.
По этим причинам и возникает вопрос: а не сломан ли equals "by-design"?