Я пытался найти библиотеку org.apache.commons.beanutils для метода / идиомы для оценки равенства всех свойств между двумя экземплярами, то есть универсальным методом equals () для beans.
Есть ли простой способ сделать это, используя эту библиотеку? Или я ошибаюсь? Спасибо.
как в целом сравнить целые java beans?
Ответы (4)
Попробуйте EqualsBuilder.reflectionEquals () из commons-lang. EqualsBuilder имеет набор методов для включения всех полей, всех непереходных полей и всех полей, кроме определенных.
Если ничего не помогает, код может служить хорошим примером того, как это реализовать.
reflectionEquals
просто вызывает equals
для каждого свойства, это больше не отражается на классе.
- person artbristol; 08.10.2012
Чтобы напрямую ответить на ваш вопрос, вы можете использовать отражение для проверки равенства bean-компонентов. Есть несколько препятствий, о которых вам нужно знать.
Существуют правила поведения 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;
}
Может быть, ты сможешь использовать это, чтобы свернуть свою собственную.
Изменить: Конечно, билдер отражения в Ответ Аарона Дигуллы намного лучше, чем мои ручные работы.
Как упоминалось выше, реализация на основе отражения будет делать то, что вы хотите. Я просто хотел предупредить вас, что рефлексия стоит довольно дорого, и такая реализация может быть сравнительно медленной. Если вам просто нужно время от времени проводить сравнения, все будет в порядке. Однако, если у вас есть огромные наборы данных и частые проверки равенства (например, фильтрация больших таблиц), у вас могут возникнуть проблемы.
Или, хотя это и не прямой ответ на ваш вопрос, но он может быть ответом на вашу проблему (т. Е. Устраните необходимость выполнять шаблонный код при сверхбыстром)
если вы используете Eclipse, следующие шаги автоматически сгенерируют hashCode и равны для вас:
Источник> Создать хэш-код и равно ...
а затем выберите поля, это супер эффективно! : D
Ура, и я надеюсь, что это поможет любому, кто приходит сюда с целью сократить время на написание шаблона.
PS: Я уверен, что другие популярные IDE должны иметь аналогичные функции.