Разница между двумя экземплярами одного класса

У меня есть два экземпляра одного класса. Мне нужно найти свойство (-ы), которое отличается от них (в основном значение свойства, например firstName может быть другим в обоих). Поля являются примитивными, сложными, а также коллекциями.

В принципе, мне нужно найти различия между двумя экземплярами, и если в обоих экземплярах поля будут разными, я скопирую значение поля из первого экземпляра в третий экземпляр (объект diff).

Я думаю, что могу использовать отражение, но классы очень сложны, и это может стать причиной ошибок.

4 ответа

Ваш вопрос немного неясен. Сначала вы сказали "два экземпляра того же класса", затем вы сказали, что "классы очень сложны". Является ли это общим решением для поиска различий между экземплярами для любого класса, или это просто конкретный случай? Другая двусмысленность - это то, что вы подразумеваете под "копией различий". Например, если это строка, то в чем разница между двумя строками, которые будут скопированы в новый экземпляр? Если это коллекция, какая разница между коллекциями? Что делать, если у вас есть два ArrayLists, которые имеют одинаковые вещи в разных порядках.

Если это конкретный случай, вы можете просто создать метод в классе, в котором вы передаете экземпляр того же класса. Затем вы можете перебирать каждое поле и сравнивать различия.

public TheClass difference(TheClass that) {
 TheClass newClass = new TheClas()
 if (this.getName().equals(that.getName()) == false ) {
 newClass.setName(that.getName());
 }
 ...
}

Но это может выйти из-под контроля в зависимости от того, насколько глубоко ваш граф объекта.

Возможно, шаблон компоновщика может пригодиться здесь, если вы пытаетесь создать универсальное/многоразовое решение. Вы можете посмотреть базу кода Apache Commons и посмотреть, как они реализуют HashCodeBuilder и ToStringBuilder. У них даже есть отраженная версия утилиты. Посмотрите, как они справляются с глубокими и неглубокими равными.


Нет другого способа, кроме как использовать отражение, если вы хотите сделать это в общем. Если у ваших полей есть геттеры, вы можете продолжить сравнение с методом equals. Затем вы знаете поля во время компиляции.


напишите метод типа

public YourClass diff(YourClass other) {
 // diff code here
}

или

public static YourClass diff(YourClass first, YourClass second) {
 // diff code here
}

и оберните некоторые модульные тесты вокруг реализаций.

Отражение может показаться более сложным, но оно имеет следующие преимущества:

1) Он может быть общим, и вы можете сделать один и тот же код с любым классом 2) Его не нужно менять, если класс эволюционирует.

Если вы хотите пойти с отражением, вы можете использовать Class.getDeclaredFields() (google для "java class api 6" ), чтобы получить все поля в классе, а затем вы можете использовать поле api для получения значений для объекта. Если вы хотите быть действительно фантастическим, у вас есть статическая String [] "diffIgnoredFields" и укажите имена полей, которые вы хотите игнорировать в diff.


Вам нужно быть осторожным. Некоторые формулировки этой проблемы в основном такие же, как Проблема изоморфизма субграфов, которая, как известно, NP завершен.

licensed under cc by-sa 3.0 with attribution.