Правило 9 (равно контракту) от Effective Java: верен ли пример?

Замечательная книга Блоха «Эффективная Java» указывает, что если равно несимметрично, то поведение Коллекций содержит неопределенно .

В приведенном им примере (воспроизведенном с небольшими изменениями ниже) Блох говорит, что он видит «ложь», но с таким же успехом мог видеть истину или исключение.

Вы можете увидеть "истину", если в стандарте не указано, содержит ли (Объект o) проверки e.equals (o) или o.equals (e ) для каждого элемента в коллекции, и первое реализовано. Однако в документации Javadoc Collections четко указано, что это должно быть последнее (и это то, что я наблюдал).

Итак, единственные возможности, которые я вижу, - это «ложь» или, возможно, исключение (но String Javadoc , похоже, исключает последнее).

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

Я что-то упускаю?

import java.util.List;
import java.util.ArrayList;

class CIString {
  private final String s;

  public CIString(String s) {
    this.s = s;
  }

  @Override public boolean equals( Object o ) {
    System.out.println("Calling CIString.equals from " + this.s );
    if ( o instanceof CIString) 
      return s.equalsIgnoreCase( ( (CIString) o).s);
    if ( o instanceof String) 
      return s.equalsIgnoreCase( (String) o );
    return false;
  }
  // Always override hashCode when you override equals
  // This is an awful hash function (everything collides -> performance is terrible!)
  // but it is semantically sound.  See Item 10 from Effective Java for more details.
  @Override public int hashCode() { return 42; }
}

public class CIS {
  public static void main(String[] args) {
   CIString a = new CIString("Polish");
   String s = "polish";

   List list = new ArrayList();
   list.add(a);
   System.out.println("list contains s:" + list.contains(s));
 }
}

5
задан Joachim Sauer 23 September 2011 в 07:34
поделиться