Java: сравнивать / сортировать произвольные объекты

Есть ли в любом случае, я могу определить последовательность / порядок для всех объектов в JVM, так что для любых двух различных объектов o1 или o2, есть четко определенное правило, которое говорит либо o1 > o2 или o2 > o1 и o1 == o2, если и только если они один и тот же объект?

Сравнение identityHashCode() было бы хорошим кандидатом, если есть гарантия отсутствия столкновений (нет).

Время рождения тоже сработало бы - если бы я мог как-то это получить.

Есть идеи?

Спасибо!

5 ответов

Решение

Все, что вам нужно сделать, это определить произвольный стабильный порядок. (Ваше "время рождения объекта" является одной из таких идей, но я не думаю, что оно сохраняется).

Метод 1: Для любых двух объектов одного и того же точного типа вы можете определить такой порядок, сравнивая их отдельные поля. Если все поля идентичны, объекты равны; если нет, какое-то поле f отличается, и вы можете определить порядок на основе базового типа. Если у вас есть два объекта с разными типами, просто используйте имя типа, чтобы определить порядок; тот, чье имя лексикографически меньше, "меньше чем". Вы можете реализовать сравнение по типу (это может быть много работы) или вы можете реализовать общее сравнение, использующее отражение, для перечисления имен и типов полей (для включения сравнения по типу), хотя это может быть довольно медленным.

Метод 2: Каждый раз, когда вы вызываете свой компаратор, кэшируйте любой объект, еще не встреченный в линейном массиве. Любые сравниваемые объекты теперь имеют индексную позицию в массиве; o1

Метод 3: Если вы работаете с определенным подмножеством объектов и существует каноническое остовное дерево, нумеруйте каждое ребро остовного дерева так, чтобы у дочерних дуг были уникальные числа. Тогда o1

Если вы можете поддерживать свой собственный репозиторий объектов, вы можете использовать WeakHashMap<Object, Long> сохранить свои собственные серийные идентификаторы.

Вам необходимо реализовать Comparable<YourObject> интерфейс и compareTo(YourObject obj) метод. Контракт метода compareTo (..) должен возвращать -1(-ve число), когда этот объект меньше, чем объект, переданный в качестве параметра, 0, когда они равны, и +1 (+ve число), если этот объект больше чем другой объект. Вы можете реализовать сравнение, используя любые поля, которые вам нравятся.

Использование Collections.sort() или любого list.sort () будет использовать этот компаратор для сортировки вашего списка.

Надеюсь это поможет!

Если ваши объекты относятся к одному типу, вы можете запомнить их номер создания в конструкторе:

class A {
    private static long count = 0;
    private long objNumber;
    public A() {
        synchronized(A.class) {
            objNumber = count;
            count++;
        }
    }
}

Object.toString() Метод должен возвращать разные значения для разных объектов в формате:

getClass().getName() + '@' + Integer.toHexString(hashCode())

Так могли бы вы сравнить сначала getClass(). GetName() в алфавитном порядке, а затем hashCode()?

Другие вопросы по тегам