Как в целом сравнить всю java beans?

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

Ответы

Ответ 1

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

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

Ответ 2

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

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

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

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

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

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;
}

Getters:

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;
}

Возможно, вы можете использовать это, чтобы катиться самостоятельно.

Изменить. reflectionbuilder в Ответ Аарона Дигуллы намного лучше, чем моя ручная работа.

Ответ 3

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

Ответ 4

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

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

Источник > Создать хэш-код и равен...

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

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

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