Ваш пример со связанным списком не так сложен в обращении. Когда код пересекает два графа объектов, он помещает посещенные объекты в набор или карту. Прежде чем перейти к другой ссылке на объект, этот набор проверяется, чтобы убедиться, что объект уже пройден. Если это так, нет необходимости идти дальше.
Я согласен с вышеупомянутым человеком, который сказал использовать LinkedList (как Stack, но без синхронизированных методов, поэтому он быстрее). Обход графа объекта с помощью стека и использование отражения для получения каждого поля является идеальным решением. Написанный один раз, этот «внешний» equals () и «внешний» hashCode () - это то, что должны вызывать все методы equals () и hashCode (). Никогда больше вам не нужен метод equals () клиента.
Я написал немного кода, который просматривает полный граф объектов, указанный в Google Code. См. Json-io (http://code.google.com/p/json-io/).. Он сериализует граф объектов Java в JSON и десериализуется из него. Он обрабатывает все объекты Java с открытыми конструкторами или без них, Сериализуемый или не Сериализуемый и т. Д. Этот же код обхода будет основой для внешняя реализация "equals ()" и внешняя реализация "hashcode ()". Кстати, JsonReader / JsonWriter (json-io) обычно быстрее, чем встроенный ObjectInputStream / ObjectOutputStream.
Этот JsonReader / JsonWriter можно использовать для сравнения, но он не поможет с хэш-кодом. Если вам нужен универсальный hashcode () и equals (), ему нужен собственный код. Я могу быть в состоянии осуществить это с обычным посетителем графика. Посмотрим.
Другие соображения - статические поля - это просто - их можно пропустить, потому что все экземпляры equals () будут иметь одинаковое значение для статических полей, так как статические поля являются общими для всех экземпляров.
Что касается переходных полей - это будет выбор по выбору. Иногда вы можете захотеть, чтобы переходные процессы не учитывались в других случаях. «Иногда ты чувствуешь себя как орешек, иногда нет».
Вернитесь к проекту json-io (для других моих проектов), и вы найдете внешний проект equals () / hashcode (). У меня пока нет названия, но это будет очевидно.