Наложить полный порядок на все экземпляры *любого* класса в Java.

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

  •  09-06-2019
  •  | 
  •  

Вопрос

Я не уверен, обеспечит ли следующий код все условия, указанные в Javadoc 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);
    }
}

Будет ли приведенный выше код навязывать полный порядок всем экземплярам любого класса, даже если этот класс не реализует Comparable?

Это было полезно?

Решение

Эй, посмотри, что я нашел!

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

Ах да, я забыл об IdentityHashMap (только для Java 6 и выше).Просто нужно обратить внимание на выпуск компаратора.

Другие советы

Эй, посмотри, что я нашел!

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

Это именно то, что я искал.

Вы ответили в своем комментарии:

Равенство вернуло ложь, но идентификационный хэш-код был таким же, предположим, что o1 == o2

К сожалению, вы не можете этого предположить.В большинстве случаев это сработает, но в некоторых исключительных случаях — нет.И вы не можете знать, когда.Когда такой случай появится, это приведет, например, к потере экземпляров в TreeSets.

Я не думаю, что это так, поскольку этот пункт не соблюдается:

Наконец, разработчик должен гарантировать, что x.compareTo(y)==0 подразумевает, что sn(x.compareTo(z)) == sgn(y.compareTo(z)), для всех z.

Поскольку равенство (o1, o2) зависит от реализации равенства в o1, два объекта, которые логически равны (как определено равными), по-прежнему имеют два разных идентификатора IHashCodes.

Поэтому при сравнении их с третьим объектом (z) они могут получить разные значения для сравненияTo.

Имеет смысл?

Вероятно, вам следует вызвать исключение, если оно дойдет до последнего return 0 строка — когда происходит хеш-коллизия.Однако, у меня есть вопрос:вы выполняете полный порядок хэшей, что, я думаю, нормально, но не следует ли передать ему какую-нибудь функцию для определения лексикографического порядка?

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

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

Я согласен, что это не идеально, отсюда и комментарий.Какие-либо предложения?

Я думаю, что теперь вы можете решить эту проблему, потому что вы не можете получить доступ к одной-единственной вещи, которая может различать два экземпляра:их адрес в памяти.Поэтому у меня есть только одно предложение:пересмотрите свою потребность в общем процессе заказа на Java :-)

Я не совсем уверен насчет System.identityHashCode(Object).Это примерно то, что == используется для.Возможно, вы захотите использовать Object.hashCode() - это больше параллельно с Object.equals(Object).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top