Как правильно использовать BeanComparator от Apache Common BeanUtil для интроспекции?

1

Я искал вокруг SOF, но не нашел такой основной вопрос, связанный с использованием BeanUtil.

У меня класс POJO, скажем, например UserPojo чей код класса:

public class UserPojo{

    private String name;
    private int    gender;
    private int    size;

    //Setters
    public void setName(String name) {this.name  =name;}
    public void setGender(int gender){this.gender=gender;}
    public void setSize(int size)    {this.size  =size;}

    //getters
    public String getName()  {return this.name;}
    public int    getGender(){return this.gender;}
    public int    getSize()  {return this.size;}
}

Мой вопрос: как использовать BeanUtil для автоматического сравнения двух экземпляров этого компонента?

Я попробовал это:

final BeanComparator<UserPojo> comparator = new BeanComparator<UserPojo>();
final int comparison = comparator.compare(expectedPojo, receivedPojo);

Но это заканчивается следующей ошибкой:

java.lang.ClassCastException : UserPojo cannot be cast to java.lang.Comparable

Я понимаю, что мой Pojo должен реализовать стандартный Comparable интерфейс, но этот способ сравнения не полагаться на самоанализ и импорт BeanUtil кажется очень бесполезно...

Итак, как правильно его использовать?

Теги:
apache-commons
javabeans
introspection
apache-commons-beanutils

2 ответа

0

Я, наконец, сдался и закодировал это. Это не отвечает на вопрос, но это мой способ решить эту проблему:

import org.apache.commons.beanutils.BeanUtils;

public static void assertBeansEqual(final Object expected, final Object given) {
    try {
        final Map<String, String> expectedDescription = BeanUtils.describe(expected);
        final Map<String, String> givenDescription = BeanUtils.describe(given);

        // if the two bean don't share the same attributes.
        if (!(expectedDescription.keySet().containsAll(givenDescription.keySet()))) {
            final Set<String> keySet = givenDescription.keySet();
            keySet.removeAll(expectedDescription.keySet());
            fail("The expected bean has not the same attributes than the given bean, the followings fields are not present in the expected bean :" + keySet);
        }
        if (!(givenDescription.keySet().containsAll(expectedDescription.keySet()))) {
            final Set<String> keySet = expectedDescription.keySet();
            keySet.removeAll(givenDescription.keySet());
            fail("The expected bean has not the same attributes than the given bean, the followings fields are not present in the given bean :" + keySet);
        }

        final List<String> differences = new LinkedList<String>();
        for (final String key : expectedDescription.keySet()) {
            if (isNull(expectedDescription.get(key))) {
                // if the bean1 value is null and not the other -> not equal. This test is
                // required to avoid NPE attributes values are null. (null object dot not have
                // equals method).
                if (!isNull(givenDescription.get(key))) {
                    differences.add(key);
                }
            }
            else {
                // if two attributes don't share an attributes value.
                if (!expectedDescription.get(key).equals(givenDescription.get(key))) {
                    differences.add(key);
                }
            }
        }
        if (!differences.isEmpty()) {
            String attributes = "";
            for (final String attr : differences) {
                attributes = attributes + "|" + attr;
            }
            fail("Assertion fail, the expected bean and the given bean attributes values differ for the followings attributes : " + attributes + "|");
        }
    }
    catch (final Exception e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
}
0

Вы должны посмотреть на различные конструкторы:

BeanComparator (свойство String)

  • Создает компаратор на основе свойств для bean-компонентов.

BeanComparator (свойство String, компаратор компаратора)

  • Создает компаратор на основе свойств для bean-компонентов.

Здесь бывший javadoc (второй пара - ваш ответ):

Создает компаратор на основе свойств для bean-компонентов. Это сравнивает два компонента по свойству, указанному в параметре свойства. Этот конструктор создает BeanComparator, который использует ComparableComparator для сравнения значений свойств.

Передача "null" этому конструктору приведет к тому, что BeanComparator будет сравнивать объекты на основе естественного порядка, то есть java.lang.Comparable.

Как и следовало ожидать, конструктор, который вы вызываете, выполняет именно это:

this(null);

Для сравнения нескольких свойств вы можете использовать второй вариант

Collections.sort(collection, 
  new BeanComparator("property1", 
    new BeanComparator("property2", 
      new BeanComparator("property3")))); 

Я лично почувствовал, что Apache Commons CompareToBuilder и Google Guavas ComparisonChain - лучший выбор.

  • 0
    Не знаю compareToBuilde и comparisonChain они позволяют автообновления боба comprarison?
  • 0
    Нет, но они помогут вам реализовать compareTo метод, так же , как EqualsBuilder поможет вам построить equals метод. Не самое большое преимущество, с которым я согласен, но необходимость указывать имена параметров (возможно, потому что он использует отражение под капотом) в BeanComparator не устраивает меня.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню