Отношение транзитивности: что такое x.equals (z), если x.equals (y) равно false, а y.equals (z) равно true - PullRequest
2 голосов
/ 24 августа 2010

Предполагая, что равно () является транзитивным; Я понимаю, что если x и y имеют двустороннее соглашение о равенстве, то один из них, скажем, y, не заключает соглашение с третьим классом z самостоятельно. Но если у нас есть ситуация, когда x.equals (y) = false (все еще переходный), тогда каким должно быть это двустороннее соглашение с z?

Ответы [ 5 ]

5 голосов
/ 24 августа 2010

Если метод equals реализован правильно, как того требует javadoc Object:

  • Это рефлексивно: для любого ненулевого ссылочного значения x, x.equals (x) должно возвращать true.
  • Это симметрично: для любых ненулевых ссылочных значений x и y x.equals (y) должно возвращать true тогда и только тогда, когда y.equals (x) возвращает true .
  • Это транзитивно: для любых ненулевых ссылочных значений x, y и z, если x.equals (y) возвращает true, а y.equals (z) возвращает true, тогда x.equals (z) должен вернуть true .
  • Это непротиворечиво: для любых ненулевых ссылочных значений x и y множественные вызовы x.equals (y) последовательно возвращают true или последовательно возвращают false, при условии что никакая информация, используемая в сравнениях сравнения объектов, не изменяется.
  • Для любого ненулевого ссылочного значения x, x.equals (null) должен возвращать false.

мы можем сделать вывод, что x.equals (z) должно быть ложным.

Докажите, если equals() транзитивно и симметрично, x.equals (y) равно false, а y.equals (z) равно true:

1) предполагая, что x.equals (z) истинно;
2) z.equals (y) верно (симметрия);
1 + 2) x.equals (y) верно (переходные 1 и 2)

но x.equals (y) задано как false, поэтому число 1 или номер 2 должно быть неправильным, то есть x.equals (z) равно false или функция не симметрична.

Но если equals() не реализовано симметрично, вы ничего не можете сказать о результате x.equals (z) (см. Другие ответы; мой комментарий к ответу @Stephen C)

2 голосов
/ 24 августа 2010

Хорошо:

x ≢ y
y ≡ z

, поскольку метод equals () является транзитивным, вы можете заменить y на z:

x ≢ z

Следовательно, x.equals (z) равно false.

Редактировать: все сводится к булевой логике, которая также транзитивна.

1 голос
/ 24 августа 2010

@ Колин Хеберт ответил на это. Я просто хотел бы указать на возможный источник путаницы ОП.

Здесь на самом деле есть два разных отношения:

  • отношение эквалайзера (т.е. x.equals(y) == true) является переходным.

  • отношение NE (т.е. x.equals(y) == false) НЕ транзитивно.

Кроме того, свойство транзитивности позволяет только рассуждать о цепях, включающих одно отношение; то есть x EQ y && y EQ Z implies x EQ Z. Вопрос пытается использовать переходность к рассуждению о x NE y && y EQ z ... и он не относится к этому случаю.

0 голосов
/ 24 августа 2010

TO @Colin HEBERT: Здесь предполагается, что метод equals () выполняет контракт отношения эквивалентности. Таким образом, для объектов x и y, если x.equals (y) возвращает false, тогда y.equals (x) также false. Это симметричные отношения между ними. Теперь для транзитивности, если у нас есть еще один объект z и y.equals (z) верно. Что должен x.equals (z) возвращать в контексте этого отношения эквивалентности, где x.equals (y) и y.equals (x) возвращают false, и почему?

0 голосов
/ 24 августа 2010

Может быть только два основных сценария:

  1. x.equals (у)

    y.equals(x)
    if x.equals(z) then y.equals(z), z.equals(x), z.equals(y)
    if !x.equals(z) then !y.equals(z), !z.equals(x), !z.equals(y)
    
  2. ! x.equals (у)

    !y.equals(x)
    if x.equals(z) then !y.equals(z), z.equals(x), !z.equals(y)
    if !x.equals(z) then !z.equals(x) // you can't know the rest for sure
    
...