Perché è .compareTo () in un'interfaccia mentre .equals () è in una classe in Java?

29

Voglio sapere perché .compareTo() si trova in Comparable interfaccia mentre un metodo come .equals si trova in Object classe. Per me, sembra arbitrario il motivo per cui un metodo come .compareTo() non è già nella classe Object .

Per utilizzare .compareTo() , implementa l'interfaccia Comparable e implementa il metodo .compareTo() per i tuoi scopi. Per il metodo .equals() , devi semplicemente eseguire l'override del metodo nella classe, poiché tutte le classi ereditano dalla classe Object .

La mia domanda è: perché un metodo come .compareTo() in un'interfaccia implementata piuttosto che in una classe come Object ? Allo stesso modo, perché il metodo .equals() nella classe Object e non in alcune interfacce deve essere implementato?

    
posta Wesley 07.05.2015 - 04:26
fonte

4 risposte

58

Non tutti gli oggetti possono essere confrontati, ma tutti gli oggetti possono essere controllati per l'uguaglianza. Se non altro, si può vedere se due oggetti esistono nella stessa posizione in memoria (uguaglianza di riferimento).

Che cosa significa compareTo() su due oggetti Thread ? In che modo un thread è "maggiore di" un altro? Come confronti due ArrayList<T> s?

Il contratto Object si applica alle classi Java tutte . Se anche una sola classe non può essere paragonata ad altre istanze della sua stessa classe, allora Object non può richiedere che faccia parte dell'interfaccia.

Joshua Bloch usa le parole chiave "ordinamento naturale" quando spiega perché una classe potrebbe voler implementare Comparable . Non tutte le classi hanno un ordinamento naturale come ho detto nei miei esempi sopra, quindi non tutte le classi dovrebbero implementare ComparableObject avere il metodo compareTo .

...the compareTo method is not declared in Object. ... It is similar in character to Object's equals method, except that it permits order comparisons in addition to simple equality comparisons, and it is generic. By implementing Comparable, a class indicates that its instances have a natural ordering.

Java efficace, seconda edizione : Joshua Bloch. Punto 12, Pagina 62. Le ellissi rimuovono i riferimenti ad altri capitoli ed esempi di codice.

Per i casi in cui fai vuoi imporre un ordinamento su una classe non Comparable che non ha un ordinamento naturale, puoi sempre fornire un'istanza Comparator per facilitare l'ordinamento.

    
risposta data 07.05.2015 - 04:41
fonte
8

Il JLS §4.3.2 definisce class oggetto nel seguente modo:

4.3.2. The Class Object

The class Object is a superclass (§8.1.4) of all other classes.

All class and array types inherit (§8.4.8) the methods of class Object, which are summarized as follows:

  • The method clone is used to make a duplicate of an object.

  • The method equals defines a notion of object equality, which is based on value, not reference, comparison.

  • The method finalize is run just before an object is destroyed (§12.6).

  • The method getClass returns the Class object that represents the class of the object.

  • A Class object exists for each reference type. It can be used, for example, to discover the fully qualified name of a class, its members, its immediate superclass, and any interfaces that it implements.

    The type of a method invocation expression of getClass is Class<? extends |T|> where T is the class or interface searched (§15.12.1) for getClass.

    A class method that is declared synchronized (§8.4.3.6) synchronizes on the monitor associated with the Class object of the class.

  • The method hashCode is very useful, together with the method equals, in hashtables such as java.util.Hashmap.

  • The methods wait, notify, and notifyAll are used in concurrent programming using threads (§17.2).

  • The method toString returns a String representation of the object.

Quindi, ecco perché equals è in Object ma compareTo è in un'interfaccia separata. Vorrei ipotizzare che volevano mantenere Object il più minimamente possibile. Probabilmente hanno calcolato che quasi tutti Objects avrebbero bisogno di equals e hashCode (che è in realtà solo una forma di test di uguaglianza) ma non tutti gli oggetti dovrebbero avere un concetto di ordinare , che è ciò per cui viene utilizzato compareTo .

    
risposta data 07.05.2015 - 04:32
fonte
2

Oltre all'eccellente risposta di Snowman, ricorda che Comparable è stata un'interfaccia generica per molto tempo. Un tipo non implementa compareTo(object) , implementa compareTo(T) dove T è il suo tipo. Questo non può essere implementato su object , poiché object non conosce la classe che sarà derivata da esso.

object potrebbe aver definito un metodo compareTo(object) , ma ciò avrebbe consentito non solo quello che Snowman indica, un confronto tra due ArrayList<T> s o tra due Thread s, ma anche un confronto tra un ArrayList<T> e a Thread . Questo è ancora più insensato.

    
risposta data 07.05.2015 - 10:01
fonte
0

Supponiamo di avere due riferimenti a oggetti: X identifica un'istanza di String contenente il contenuto "George"; Y identifica l'istanza di Point che mantiene le coordinate [12,34]. Considera le seguenti due domande:

  • X e Y identificano oggetti equivalenti?

  • Si dovrebbe ordinare X prima, dopo o equivalente a Y?

Il fatto che X e Y identificano istanze di tipi non correlati non pone alcun problema quando si considera la prima domanda. Gli oggetti possono essere considerati equivalenti solo se i loro tipi condividono una base comune che li definisce come equivalenti; poiché String e Point non hanno tale base (il loro unico tipo di base comune considera tutti gli oggetti distinti come non equivalenti) la risposta è semplicemente "no".

Il fatto che i tipi non siano correlati, tuttavia, pone un grosso problema per quanto riguarda la seconda domanda. Alcuni tipi definiscono le relazioni di ordinamento tra le loro istanze e alcune relazioni di ordinamento possono persino estendersi su più tipi [ad es. sarebbe possibile per BigInteger e BigDecimal definire metodi di confronto che consentano di classificare le istanze di entrambi i tipi rispetto alle istanze dell'altro], ma in generale non è possibile prendere due istanze arbitrarie e chiedere "Dovrebbe X ordinamento prima, dopo o equivalente a Y "e derivano un ordinamento totale. Sarebbe possibile chiedere "Se X ordina prima, dopo, equivalente o non classificato rispetto a Y" se agli oggetti è richiesto di segnalare un ordinamento coerente sebbene non sia un totale uno, ma la maggior parte degli algoritmi di ordinamento richiede ordini totali. Quindi, anche se tutti gli oggetti potessero implementare un metodo compareTo se "unranked" fosse un ritorno valido, un tale metodo non sarebbe abbastanza utile per giustificare la sua esistenza.

    
risposta data 07.05.2015 - 21:12
fonte

Leggi altre domande sui tag