Imposer un ordre total à toutes les instances de *n'importe quelle* classe en Java

StackOverflow https://stackoverflow.com/questions/28301

  •  09-06-2019
  •  | 
  •  

Question

Je ne sais pas si le code suivant garantirait toutes les conditions données dans le Javadoc de Comparator.

class TotalOrder<T> implements Comparator<T> {

    public boolean compare(T o1, T o2) {
        if (o1 == o2 || equal(o1, o2)) return 0;

        int h1 = System.identityHashCode(o1);
        int h2 = System.identityHashCode(o2);

        if (h1 != h2) {
            return h1 < h2 ? -1 : 1;
        }

        // equals returned false but identity hash code was same, assume o1 == o2
        return 0;
    }

    boolean equal(Object o1, Object o2) {
        return o1 == null ? o2 == null : o1.equals(o2);
    }
}

Le code ci-dessus imposera-t-il un ordre total sur toutes les instances d'une classe, même si cette classe n'implémente pas Comparable ?

Était-ce utile?

La solution

Hé, regarde ce que j'ai trouvé !

http://gafter.blogspot.com/2007/03/compact-object-comparator.html

Oh oui, j'ai oublié IdentityHashMap (Java 6 et supérieur uniquement).Il vous suffit de faire attention à la sortie de votre comparateur.

Autres conseils

Hé, regarde ce que j'ai trouvé !

http://gafter.blogspot.com/2007/03/compact-object-comparator.html

Ceci est exactement ce que je cherchais.

Vous avez répondu dans votre commentaire :

égal a renvoyé faux mais le code de hachage d'identité était le même, supposons que o1 == o2

Malheureusement, vous ne pouvez pas supposer cela.La plupart du temps, cela fonctionnera, mais dans certains cas exceptionnels, cela ne fonctionnera pas.Et on ne peut pas savoir quand.Lorsqu'un tel cas apparaît, cela entraînerait une perte d'instances dans les TreeSets par exemple.

Je ne pense pas que ce soit le cas puisque cette clause n'est pas respectée :

Enfin, l'implémenteur doit s'assurer que x.compareTo(y)==0 implique que sgn(x.compareTo(z)) == sgn(y.compareTo(z)), pour tout z.

Puisque égal(o1, o2) dépend de l'implémentation d'égaux par o1, deux objets logiquement égaux (tels que déterminés par égaux) ont toujours deux codes d'identité différents.

Ainsi, lorsqu'on les compare à un troisième objet (z), ils peuvent finir par donner des valeurs différentes pour compareTo.

Cela a du sens ?

Vous devriez probablement lever une exception si cela arrive en dernier return 0 line --quand une collision de hachage se produit.Par contre, j'ai une question:vous effectuez un ordre total sur les hachages, ce qui, je suppose, est bien, mais une fonction ne devrait-elle pas lui être transmise pour définir un ordre lexicographique ?

    int h1 = System.identityHashCode(o1);
    int h2 = System.identityHashCode(o2);
    if (h1 != h2) {
        return h1 < h2 ? -1 : 1;
    }

J'imagine que vous avez les objets sous forme de tuple de deux entiers qui forment un nombre réel.Mais vous n'obtiendrez pas le bon ordre puisque vous ne prenez qu'un hachage de l'objet.Tout dépend de vous si vous vouliez dire hachage, mais pour moi, cela n'a pas beaucoup de sens.

Je suis d'accord que ce n'est pas idéal, d'où le commentaire.Aucune suggestion?

Je pense qu'il existe désormais un moyen de résoudre ce problème, car vous ne pouvez pas accéder à la seule et unique chose qui peut distinguer deux instances :leur adresse en mémoire.Je n'ai donc qu'une seule suggestion :reconsidérez votre besoin d'avoir un processus de commande total général en Java :-)

Je ne suis pas vraiment sûr du System.identityHashCode(Object).C'est à peu près ce que == est utilisé pour.Vous préférerez peut-être utiliser le Object.hashCode() - c'est plus en parallèle avec Object.equals(Object).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top