Утверждают, что два Java-бина эквивалентны

В дополнение к ответу DCookie выше, вы также можете использовать chr (39) для отдельной цитаты.

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

Вот очень простой пример:

Select 'UPDATE Customers SET LName = ' || chr(39) || 'Doe' || chr(39) || ';' From dual;
13
задан Community 23 May 2017 в 12:32
поделиться

7 ответов

Первый вопрос, который я должен задать, заключается в том, хотите ли вы сделать «глубокое» равенство на Бине? есть ли у него дочерние бины, которые нужно протестировать? Вы можете переопределить метод equals, но он возвращает только логическое значение, поэтому вы можете создать «компаратор», который мог бы вызвать исключение с сообщением о том, что не было равно.

В следующих примерах я перечислил несколько способов реализовать метод equals.

если вы хотите проверить, являются ли они одним и тем же экземпляром объекта, то вам сообщит обычный метод equals из Object.

    objectA.equals(objectB);

если вы хотите написать метод равного для клиента, чтобы проверить это все переменные-члены объекта делают их равными, тогда вы можете переопределить метод equals следующим образом ...

  /**
     * Method to check the following...
     * <br>
     * <ul>
     *    <li>getTitle</li>
     *    <li>getInitials</li>
     *    <li>getForename</li>
     *    <li>getSurname</li>
     *    <li>getSurnamePrefix</li>
     * </ul>
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj)
    {
      if (   (!compare(((ICustomer) obj).getTitle(), this.getTitle()))
          || (!compare(((ICustomer) obj).getInitials(), this.getInitials()))
          || (!compare(((ICustomer) obj).getForename(), this.getForename()))
          || (!compare(((ICustomer) obj).getSurname(), this.getSurname()))
          || (!compare(((ICustomer) obj).getSurnamePrefix(), this.getSurnamePrefix()))
          || (!compare(((ICustomer) obj).getSalutation(), this.getSalutation()))  ){
          return false;
      }
      return true;
    }

Последний вариант - использовать отражение Java для проверки всех переменных-членов в методе equals. Это замечательно, если вы действительно хотите проверить каждую переменную-член с помощью метода get / set bean-компонента. Это не (я не думаю) позволяет вам проверять частные переменные членов, когда тестирование двух объектов одинаково. (нет, если ваша объектная модель имеет циклическую зависимость, не делайте этого, она никогда не вернется)

ПРИМЕЧАНИЕ: это не мой код, он исходит из ...

Java Reflection равно public static boolean равно (Object bean1, Object bean2) { // Обрабатываем тривиальные случаи если (bean1 == bean2) return true;

if (bean1 == null)
return false;

if (bean2 == null)
return false;

// Get the class of one of the parameters
Class clazz = bean1.getClass();

// Make sure bean1 and bean2 are the same class
if (!clazz.equals(bean2.getClass()))
{
return false;
}

// Iterate through each field looking for differences
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++)
{
// setAccessible is great (encapsulation
// purists will disagree), setting to true
// allows reflection to have access to
// private members.
fields[i].setAccessible(true);
try
{
Object value1 = fields[i].get(bean1);
Object value2 = fields[i].get(bean2);

if ((value1 == null && value2 != null) ||
(value1 != null && value2 == null))
{
return false;
}

if (value1 != null &&
value2 != null &&
!value1.equals(value2))
{
return false;
}
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}

return true;

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

0
ответ дан 1 December 2019 в 19:23
поделиться

На самом деле вы не утверждаете равенство, а скорее делаете «различие». Ясно, что значение слова «одинаковый» зависит от конкретной логики для каждого типа, и представление различия также может варьироваться. Одно из основных различий между этим требованием и обычным equals () состоит в том, что обычно equals () останавливается, как только будет замечено первое различие, вы захотите продолжить и сравнить каждое поле.

Я бы рассмотрел возможность повторного использования некоторых из них. шаблоны equals (), но я подозреваю, что вам придется написать свой собственный код.

0
ответ дан 1 December 2019 в 19:23
поделиться

(основываясь на моем комментарии к Andreas_D выше)

/** Asserts two objects are equals using a reflective equals.
 * 
 * @param message The message to display.
 * @param expected The expected result.
 * @param actual The actual result
 */
public static void assertReflectiveEquals(final String message, 
        final Object expected, final Object actual) {
    if (!EqualsBuilder.reflectionEquals(expected, actual)) {
        assertEquals(message, 
                reflectionToString(expected, ToStringStyle.SHORT_PREFIX_STYLE), 
                reflectionToString(actual, ToStringStyle.SHORT_PREFIX_STYLE));
        fail(message + "expected: <" + expected + ">  actual: <" + actual + ">");
    }
}

Это то, что я использую, и я считаю, что он отвечает всем основным требованиям. Выполнив assert для отражающей ToString, Eclipse выделит разницу.

Хотя Hamcrest может предложить гораздо более приятное сообщение, это требует гораздо меньшего количества кода.

0
ответ дан 1 December 2019 в 19:23
поделиться

Поскольку вам не понравились ответы в упомянутом вами вопросе, почему бы просто не использовать метод toXml в каждом bean-компоненте, превратить его в файл xml и затем использовать xmlUnit для сравнения.

Дополнительную информацию о сравнении файлов XML можно найти здесь:

Лучший способ сравнить 2 документа XML в Java

0
ответ дан 1 December 2019 в 19:23
поделиться

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

Определите класс утилиты (общедоступный статический финал с частным ctor) называется, скажем, BeanAssertEquals. Используйте отражение Java, чтобы получить значение каждой переменной-члена в каждом компоненте. Затем выполните equals () между значениями одной и той же переменной-члена в разных bean-компонентах. Если равенство не удается, укажите имя поля.

Примечание: переменные-члены обычно являются закрытыми, поэтому вам нужно будет использовать отражение, чтобы временно изменить доступность закрытых членов.

Кроме того, в зависимости от того, насколько детально вы хотите, чтобы Чтобы утверждение работало, вы должны учитывать следующее:

  1. Равенство переменных-членов не в классе компонента, а во всех суперклассах.

  2. Равенство элементов в массивах, в случае, если переменная-член имеет тип array.

  3. Для двух значений данного члена в разных bean-компонентах вы можете рассмотреть возможность выполнения BeanAssertEquals.assertEquals (value1, value2) вместо value1.equals (value2).

0
ответ дан 1 December 2019 в 19:23
поделиться

Я думаю, что наиболее общий подход состоит в том, чтобы отразить члены компонента и проверить их на равенство один за другим. Общий язык EqualsBuilder - хорошее начало, и адаптировать его (на уровне исходного кода) к вашим требованиям (на уровне исходного кода) в соответствии с вашими требованиями (отчет о различиях вместо того, чтобы возвращать результат равенства) не представляет особой сложности.

1
ответ дан 1 December 2019 в 19:23
поделиться

Вы можете использовать Commons Lang ToStringBuilder , чтобы преобразовать их оба в читаемые строки, а затем использовать assertEquals () для обеих строк.

Если вам нравится XML, вы можете использовать java.lang.XMLEncoder , чтобы преобразовать ваш bean-компонент в XML, а затем сравнить два XML-документа.

Лично я предпочитаю ToStringBuilder , поскольку он дает вам больше контроля над форматированием и позволяет вам делать такие вещи, как сортировка элементов в наборе, чтобы избежать ложноотрицательных результатов.

Я предлагаю поместить каждое поле компонента в отдельную строку, чтобы сделать его гораздо проще их сравнить ( подробности см. в моем блоге ).

4
ответ дан 1 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: