2011-05-26 18 views
6

Estoy tratando de implementar el método equals para las clases Java Book y Chapter en mi aplicación. Book tiene un conjunto de Chapter s, mientras que Chapter tiene asociado Book. La asociación bidireccional se muestra a continuación:método equals() para las clases con asociación bidireccional

class Book{ 
    private String isbn; 
    private String name; 
    private Date publishDate; 
    private Set<Chapter> chapters; 
    ... 

    public boolean equals(Object o){ 
     if(o == this){ 
      return true; 
     } 
     if (!(o instanceof Book)){ 
      return false; 
     } 
     Book book = (Book)o; 
     if((this.isbn.equals(book.getIsbn())) && (this.name.equals(book.getName())) &&(this.publishDate.equals(book.getPublishDate())) &&(this.chapters.equals(book.getChapters()))){ 
      return true; 
     }else{ 
      return false; 
     } 

    } 
} 

Ahora me trató de implementar equals para Chapter:

public class Chapter { 
    private String title; 
    private Integer noOfPages; 
    private Book book; 
    ... 

    public boolean equals(Object o){ 
     if(o == this){ 
      return true; 
     } 
     if (!(o instanceof Chapter)){ 
      return false; 
     } 
     Chapter ch = (Chapter)o; 
     if((this.title.equals(book.getTitle())) && (this.noOfPages.intValue()== book.getNoOfPages().intValue()) ){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 

} 

Aquí, me pregunto si tengo que comparar el campo libro también. ¿No comenzaría eso un ciclo infinito? ¿Cuál es la forma correcta de implementar el método equals para tales asociaciones bidireccionales?

Respuesta

1

(supongo que es Java) En el método de la clase Chapter es igual, podría simplemente comparar las referencias del libro (es decir, usando ==, no iguales). Esto solo compara las referencias, por lo que evitaría un ciclo infinito. Sin embargo, si clona libros a veces, este enfoque fracasaría.

Una forma aún mejor de resolver este caso específico sería comparar no los libros, sino su ISBN, ya que es un identificador único para un Libro.

En general, es mejor evitar dependencias bidireccionales como esta. Una forma es hacer que una de las dos clases implemente una interfaz, para no usarla directamente.

+1

Aunque el uso de interfaces evita la dependencia bidireccional entre las clases, aún existe una dependencia bidireccional entre las instancias en tiempo de ejecución. Así que sugiero que no se deben comparar los libros (ya sea por '==' o 'igual()'), pero simplemente se ignoran los libros (¿son dos capítulos idénticos de diferentes libros realmente iguales o diferentes?), O se compara un libro identificador como el ISBN. –

+0

Estoy completamente de acuerdo, acabo de comentar sobre la dependencia circular ya que me enseñaron a evitarlos siempre que sea posible. –

1

Desde una perspectiva de modelado, el capítulo es parte del libro. Entonces, aunque tiene referencias en ambas direcciones, el libro es "más fuerte" que el capítulo.

Cuando tiene relaciones de parte de como Libro y Capítulo, la parte (Capítulo) a veces toma todo (Libro) en cuenta al definir equals(). Pero no al revés.

Así que, claramente, el libro no usaría sus capítulos para definir equals(). El capítulo podría usar el libro. Eso depende del modelo.

4

Un libro debe ser igual a otro libro solo si sus ISBN son iguales. Así que implementar el libro es igual solo basado en ese campo.

Para el capítulo - comparar el número de capítulo y el poseer Book

1

Tienes que elegir un campo Book como una identificación (como el ISBN). Luego, en Chapter iguales, se puede hacer una cosa así

book.getISBN().equals(other.book.getISBN()) 
Cuestiones relacionadas