Отношение эквивалентности и естественный порядок на классе в Java

Я очень хорошо понял разницу между интерфейсами Comparable и Comparator, и как таковой порядок, навязанный ими.

Кроме того, мне ясно, почему CompareTo должно соответствовать методу equals. Из документов Oracle,

Настоятельно рекомендуется (хотя и не обязательно), чтобы естественные порядки соответствовали равным. Это так, потому что отсортированные наборы (и отсортированные карты) без явных компараторов ведут себя "странно", когда они используются с элементами (или ключами), чье естественное упорядочение несовместимо с равенством. В частности, такой отсортированный набор (или отсортированная карта) нарушает общий контракт для набора (или карты), который определяется в терминах метода equals.

Например, если добавить два ключа a а также b такой, что (!a.equals(b) && a.compareTo(b) == 0) для отсортированного набора, в котором не используется явный компаратор, вторая операция добавления возвращает значение false (и размер отсортированного набора не увеличивается), поскольку a и b эквивалентны с точки зрения отсортированного набора.

Тем не менее, я не могу очистить себя от пункта (ниже),

Для математически наклоненного отношения, которое определяет естественный порядок в данном классе C, имеет вид:

    {(x, y) such that x.compareTo(y) <= 0}.

Коэффициент для этого общего заказа:

    {(x, y) such that x.compareTo(y) == 0}.

Это следует непосредственно из договора на compareTo что частное отношение является отношением эквивалентности на C, и что естественное упорядочение является полным порядком на C. Когда мы говорим, что естественное упорядочение класса согласуется с равенствами, мы имеем в виду, что частное для естественного упорядочения является отношением эквивалентности, определяемым класс equals(Object) метод:

    {(x, y) such that x.equals(y)}.  

Что автор пытается предложить здесь? Может кто-нибудь объяснить на простом примере.

3 ответа

В основном это говорит о том, что в соответствии с равными означает, что набор (x, y) пары для которых x.compareTo(y) == 0 является true идентично набору (x, y) пары для которых x.equals(y) является true,

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

Допустим, вы создаете этот глупый класс

public class A implements Comparable<A> {
  private int value;

  public A(int value){
    this.value = value }

  public boolean equals(Object obj){ 
     if (obj instanceof A)
        return this.value = ((A)obj).value;
     else return false;
  }

  public int compareTo(A another){
     return 0;
  }
}

Затем вы создаете два экземпляра:

A a1 = new A(3);
A a2 = new A(4);
SortedSet<A> set = new TreeSet<A>();
set.add(a1);
set.add(a2);

SortedSet принимает a1, но не принимает a2, потому что a1.equals(a2) == false, но a2.compareTo(a2) == 0; Помните, что в наборе для определения все элементы отличаются друг от друга (это похоже на математическую концепцию множества).

Это все математика! (х, у) означает "х относится к у"

Отношение эквивалентности - это отношение к совокупности элементов (в данном случае экземпляров класса C), которое является отражающим, симметричным и переходным.

отражающее означает: что каждый элемент относится к самому себе, симметричные средства: если a относится к b, то b относится к переходному средству: если a относится к b, а b относится к c, то a относится к c.

таким образом, отношение отношения x.compareTo (y) == 0, таким образом, является отношением эквивалентности, поскольку для каждого экземпляра c в C: c.compareTo (c) предполагается равным нулю, для каждого экземпляра c1, c2 из C: если c1.comparTo (c2) == 0, тогда c2.compareTo (c1) также должно быть равно нулю. И для всех c1, c2, c3, где c1.compareTo (c2) равно нулю, а c2.compareTo (c3) равно нулю, тогда c1.compareTo (c3) также должно быть равно нулю.

Общий порядок - это отношение, которое является транзитивным (см. Выше), антисимметричным (снова см. Выше, но теперь инвертированным, поскольку оно является анти-) и итоговым, следовательно, CompareTo должно отражать общий порядок: если a.compareTo (b) равен <= 0 и b.compareTo (c) <= 0, тогда a.compareTo (c) должно быть <= 0, если a.compareTo (b) <= 0, тогда b.compareTo (a) должно быть>= 0

total означает, что либо a.compareTo (b) <= 0, либо b.compareTo (a) <= 0, значение total означает, что любой элемент можно сравнить с другим элементом, поэтому все элементы можно упорядочить, чтобы порядок был полным.

частное происходит от a.compareTo (b) <= 0 и b.compareTo (a) <= 0, следовательно, a.compareTo (b) == 0

Я надеюсь, что это немного более объяснительно, чем оригинал...

Другие вопросы по тегам