как в целом сравнить целые бобы Java? - PullRequest
18 голосов
/ 23 января 2009

Я пытался найти в библиотеке org.apache.commons.beanutils метод / идиому для оценки на равенство все свойства между двумя экземплярами, т.е. универсальный метод equals () для bean-компонентов. 1003 * Есть ли простой способ сделать это с помощью этой библиотеки? Или я иду по этому пути неправильно? Спасибо.

Ответы [ 4 ]

19 голосов
/ 23 января 2009

Попробуйте EqualsBuilder.reflectionEquals () из commons-lang . EqualsBuilder имеет набор методов для включения всех полей, всех непереходных полей и всех полей, кроме определенных.

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

7 голосов
/ 23 января 2009

Чтобы ответить на ваш вопрос напрямую, вы можете использовать рефлексию для проверки равенства компонентов. Есть несколько препятствий, о которых вам нужно знать.

Существуют правила поведения equals () и hashcode (). Эти правила говорят о симметрии, согласованности и рефлексивности, что может быть трудно сделать, когда ваш метод equals ведет себя динамически на основе другого объекта, который вы передаете.

Интересно читать: http://www.geocities.com/technofundo/tech/java/equalhash.html

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

Сказав все это, вот несколько (в старом стиле) методов для получения геттеров, сеттеров и свойств, которые я написал давно:

private Map getPrivateFields(Class clazz, Map getters, Map setters) {
    Field[] fields = clazz.getDeclaredFields();
    Map m = new HashMap();
    for (int i = 0; i < fields.length; i++) {
        int modifiers = fields[i].getModifiers();
        if (Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
            String propName = fields[i].getName();
            if (getters.get(propName) != null && setters.get(propName) != null) {
                m.put(fields[i].getName(), fields[i]);
            }
        }
    }
    return m;
}

Геттеры:

private Map getGetters(Class clazz) {
    Method[] methods = clazz.getMethods();
    Map m = new HashMap();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName().startsWith("get")) {
            int modifiers = methods[i].getModifiers();
            if (validAccessMethod(modifiers)) {
                m.put(getPropertyName(methods[i].getName()), methods[i]);
            }
        }
    }
    return m;
}

И сеттеры:

private Map getSetters(Class clazz, Map getters) {
    Method[] methods = clazz.getMethods();
    Map m = new HashMap();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName().startsWith("set")) {
            int modifiers = methods[i].getModifiers();
            String propName = getPropertyName(methods[i].getName());
            Method getter = (Method) getters.get(propName);

            if (validAccessMethod(modifiers) && getter != null) {
                Class returnType = getter.getReturnType();
                Class setType = methods[i].getParameterTypes()[0];
                int numTypes = methods[i].getParameterTypes().length;

                if (returnType.equals(setType) && numTypes == 1) {
                    m.put(propName, methods[i]);
                }
            }
        }
    }
    return m;
}

Может быть, вы можете использовать это, чтобы бросить свой собственный.

Редактировать: Конечно, строитель отражений в Ответ Аарона Дигуллы намного лучше, чем моя ручная работа.

2 голосов
/ 23 января 2009

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

0 голосов
/ 30 января 2016

Или, хотя это и не является прямым ответом на ваш вопрос, но это может быть ответом на вашу проблему (то есть, снимите с себя труд при выполнении стандартного кода , пока очень быстро)

если вы используете Eclipse, следующие шаги автоматически сгенерируют hashCode и будут равны для вас:

Источник> Создать hashCode и равно ...

, а затем выберите поля, это супер эффективно! : D

Приветствия, и я надеюсь, что это поможет тем, кто приходит сюда с целью сократить время написания шаблонов.

PS: я уверен, что другие популярные IDE должны иметь аналогичные функции.

...