Сравнение байтового массива Java для двух dto с использованием Arrays.equals - PullRequest
1 голос
/ 26 ноября 2011

У меня есть два DTO, которые нужно сравнить с помощью (Arrays.equals), они никогда не будут равными.Данные в обоих DTO равны, когда я проверяю каждый атрибут, иногда его длина равна, но Arrays.equals возвращает false, я пытаюсь использовать Arrays.deepEquals, такая же проблема существует, но в некоторых полях.При отладке я обнаружил, что:

1 - метод хеш-кода не одинаков в обоих DTO.
2 - проблемы в атрибутах типа String.

Мой вопрос: как я могу проверитьи определить, какие атрибуты отличаются.

Вот моя привязка кода:

    Boolean isEqual = false;
    ByteArrayOutputStream bStream = new ByteArrayOutputStream();
    ObjectOutputStream oStream;

    ByteArrayOutputStream bStream2 = new ByteArrayOutputStream();
    ObjectOutputStream oStream2;

    try {
        oStream = new ObjectOutputStream(bStream);
        oStream.writeObject(obj1);
        byte[] obj1ByteArray = bStream.toByteArray();

        oStream2 = new ObjectOutputStream(bStream2);
        oStream2.writeObject(obj2);
        byte[] obj2ByteArray = bStream2.toByteArray();
        System.out.println("Obj1>>" + obj1ByteArray.length);
        System.out.println("Obj2>>" + obj2ByteArray.length);
        isEqual = Arrays.equals(obj1ByteArray, obj2ByteArray);

        oStream.close();
        oStream2.close();

привязка данных:

    Length
Obj1>>709
Obj2>>709
------------------------------------------------
Object 1
com.beshara.hr.core.interfaces.web.job.shared.structure.dto.JobDTO@1ab5140
59
test_job_5555555
-100
59
1
وظيفة تجريبية 6
وظيفة تجريبية 6أخري
10
10
10.0
وظيفة تجريبية الغرض من الوظيفة 6

--------------------------------
Object 2
com.beshara.hr.core.interfaces.web.job.shared.structure.dto.JobDTO@4cfc52
59
test_job_5555555
0
59
1
وظيفة تجريبية 6
وظيفة تجريبية 6أخري
10
10
10.0
وظيفة تجريبية الغرض من الوظيفة 6

Спасибо.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2011

Некоторые замечания, но не решение:

  • Вопреки названию вашего вопроса не Arrays.equals - это ваша проблема, а вывод ObjectOutputStream. И даже это может быть не так - это может быть проблема с кодировкой Unicode (см. Ниже).

  • Пожалуйста, приведите короткий, самостоятельный и правильный пример . Ваш код пропускает реальные входные данные. Это складывается со следующим пунктом:

  • Большинство читателей StackOverflow не могут ничего сделать изредка особенного характера испанских, французских, немецких ... сценариев. Не говоря уже о полных арабских словах. Это ограничивает число людей, которые хотят серьезно подумать о вашей проблеме.

Наконец, кое-что к самой проблеме: две разные строки Unicode могут отображаться одинаково благодаря способу Unicode разрешать комбинации символов. Итак, общий совет: сварите свою проблему как можно дальше.

  • Сравните каждую пару строк в ваших DTO с String.equals.
  • Каждая пара, которая возвращает false, но отображается таким же образом, должна быть дополнительно изучена: введите их в java.text.Normailzer, используя NFC и NFKC, и сравните результаты еще раз.
  • Если результаты сравниваются сейчас, у вас проблемы с кодировкой Unicode. Запишите свои результаты, подготовьте новые примеры и покопайте этот сайт с новыми поисковыми фразами.

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

О, я чуть не забыл: Вы заявили

У меня есть два DTO, которые нужно сравнить, используя ...

Вам следует подумать о том, чего вы действительно хотите достичь, и , а затем решить , как сделать это. Если вы хотите сравнить байты, используйте Arrays.equals. Если вы хотите сравнивать DTO, то создайте свой собственный метод сравнения, сравнивая каждое поле в DTO, выполняя любую причудливую «нормализацию». Инструмент, который поможет вам в этом, может быть Apache EqualsBuilder .

0 голосов
/ 26 ноября 2011

Как указано в Arrays.equals(byte[],byte[]) документации :

Два массива считаются равными, если оба массива содержат одинаковое количество элементов, а все соответствующие пары элементов в двух массивах равны. Другими словами, два массива равны, если они содержат одинаковые элементы в одинаковом порядке .

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

Если вы не имеете (или не хотите) контролировать, как сериализуются ваши объекты, то вы, вероятно, можете использовать какой-то Comparator<byte[]>.

public final class MyComparator implements Comparator<byte[]> {

  private static final int ATTR_START = 0;
  private static final int ATTR_END = 7;

  @Override
  public int compare(byte[] left, byte[] right) {
    if (left.length != right.length)
      return left.length - right.length;

    byte[] leftAttr = Arrays.copyOfRange(left, ATTR_START, ATTR_END);
    byte[] rightAttr = Arrays.copyOfRange(left, ATTR_START, ATTR_END);

    return Arrays.equals(leftAttr, rightAttr) ? 0 : -1;
  }
}

Я понимаю, что это немного хитроумно, так что вот еще один взгляд на проблему.

public final class MyByteArrayOutputStream extends ByteArrayOutputStream {

  private static final int ATTR_START = 0;
  private static final int ATTR_END = 7;

  @Override
  public int hashCode() {
    // this can be implemented based on *your* attribute/attributes
    // and its/their location in the buffer too, like in equals just below
    return Arrays.hashCode(buf);
  }

  @Override
  public boolean equals(Object object) {
    boolean equals = false;
    if (object instanceof MyByteArrayOutputStream) {
      MyByteArrayOutputStream other = (MyByteArrayOutputStream) object;
      byte[] thisAttr = Arrays.copyOfRange(buf, ATTR_START, ATTR_END);
      byte[] otherAttr = Arrays.copyOfRange(other.buf, ATTR_START, ATTR_END);

      if (Arrays.equals(thisAttr, otherAttr)) {
        byte[] thisRest = Arrays.copyOfRange(buf, ATTR_END, buf.length);
        byte[] otherRest = Arrays.copyOfRange(other.buf, ATTR_END, buf.length);

        equals = Arrays.equals(thisRest, otherRest);
      }
    }
    return equals;
  }
}

Подкласс ByteArrayOutputStream и реализуйте свою собственную логику равных.

...