Попытка сравнить два объекта и извлечь третий объект, содержащий их различия - PullRequest
4 голосов
/ 13 марта 2012

У меня есть два объекта домена одного типа.Они содержат перечисления, примитивные массивы и другие объекты, а также список в Heirarchy.

Мне нужно что-то извлечь для извлечения третьего объекта того же типа, который содержит только их различия, почти как маска, которая содержит только их изменения.И все, что не изменилось, должно быть установлено в null.

Все указывает на Apache BeanUtils, но я не могу найти именно то, что я ищу, какие-либо предложения?

Edit # 1 Примеруточнить: если obj1 является оригиналом, а obj2 - обновленной версией.Тогда, если obj1.value равно obj2.value, тогда obj3.value будет нулевым.Если obj1.value не равно obj2.value, то для obj3.value будет установлено значение obj2.value

Edit # 2 В идеале он должен быть абстрактным и ни в коем случае не должен знать, какой тип объектасравнение продолжается.Как это может быть использовано для различных объектов в будущем.Если для одного из значений обновления задано значение NULL, его можно игнорировать, как если бы оно не было изменением.

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Ваш вопрос мне интересен.Я очень ищу ваши цели и нахожу небольшую библиотеку, делающую это.Эта библиотека находится в google code и ее имя jettison.У этой утилиты есть основной класс с именем Diff4J, который имеет метод с методом diffs и сравнивает два объекта и находит различия.

Затем я пишу коды для ваших целей следующим образом:

fisrt определяет Model Object с именем Bean:

public class Bean
{
    private String  name;
    private String  family;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getFamily()
    {
        return family;
    }

    public void setFamily(String family)
    {
        this.family = family;
    }

    public Bean()
    {
    }

    public Bean(String name, String family )
    {
        this.name = name;
        this.family = family;
    }
}

Затем кодирует тестовый класс следующим образом:

public static void main(String[] args) throws IllegalAccessException, 
                                              InvocationTargetException
{
        Bean bean_1 = new Bean("Sara", "clooney");
        Bean bean_2 = new Bean("Sally", "clooney");

        Diff4J comparator = new Diff4J();
        Collection<ChangeInfo> diffs = comparator.diff(bean_1, bean_2);

        Bean final_result = new Bean();

        for(ChangeInfo c : diffs)
        {
            String filedName = c.getFieldName();
            Object to_value = c.getTo();
            Object from_value = c.getFrom();

            BeanUtilsBean.getInstance().setProperty(final_result, filedName, to_value);
        }

        System.out.println(final_result);

}

По этому решению, если вы запустите этот код, см. Следующеерезультат:

Bean [family=null, name=Sally]

это результат ваших целей.

Примечание: В последней строке оператора цикла я использовал BeanUtilBean из Apache Commons Util для объекта заполненияby Reflection.

У этой утилиты есть проблема, она не поддерживает Deep Comparator (возможно, я не смог ее найти), и вам нужно смоделировать эту задачу.

для просмотраэта библиотека находится по адресу http://code.google.com/p/jettison/.

Надеюсь, этот ответ поможет вам.

1 голос
/ 13 марта 2012

Это можно сделать без какой-либо внешней библиотеки;)

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

public class Bean {
  public String value;
  public List<String> list;
  public String[] array;
  public EnumType enum;
}

и добавим статический (фабричный) метод:

public static Bean createDelta(Bean master, Bean variant) {
  Bean delta = new Bean();

  // fields are simple
  if (!master.value.equals(variant.value))
     delta.value = variant.value;

  // enums are simple too
  if (master.enumValue != variant.enumValue)
     delta.value = variant.value;

  // for arrays .. it get's slightly difficult, because arrays may vary in size
  int size = master.array.length > variant.array.length ? 
               master.array.length : variant.array.length;
  delta.array = new String[size];
  for (int i = 0; i < size; i++) {
    if ((i >= master.array.length) || 
        (!master.array[i].equals(variant.array[i]))) {
       delta.array[i] = variant.array[i];

  // same pattern for lists - except we have to add null
  int size = master.array.length > variant.array.length ? 
               master.array.length : variant.array.length;
  delta.list = new ArrayList<String>();
  for (int i = 0; i < size; i++) {
    if ((i >= master.array.length) || 
        (!master.array[i].equals(variant.array[i]))) {
       delta.list.add(variant.get(i));
    } else {
       delta.list.add(null);
    }
  }
}

(Примечание - не тестировалось, нет IDE / компилятора под рукой - но это показывает общий подход)

...