Как сравнить два объекта, не зная их типа

Я реализую класс отсортированного списка, в этом классе я собираюсь сортировать любые объекты, так что теперь я хочу проверить, является ли объект сопоставимым или нет,

я использовал этот код, чтобы переопределить метод CompareTo():-

class MyObject implements Comparable {

Object ob;

    MyObject(){
        this.ob=new Object();
    }

    public int compareTo(Object current){
        if((ob.toString().compareTo(current.toString()))>1)
        return 1;
        else if((ob.toString().compareTo(current.toString()))<1)
        return -1;
        else
        return 0;

    }

    public String toString(){

        return (String)ob;
    }
}

так что теперь мне нужно присвоить номера этим объектам, как это

class SortedListTest{
    public static void main (String arg[]){

        MyObject b1= new MyObject();
        MyObject b2= new MyObject();

        b1.ob=6;
        b2.ob=3;

        System.out.println(b2.compareTo(b1));
    }

}

но он продолжает давать мне это исключение:

Исключение в потоке "main" java.lang.ClassCastException: java.lang.Integer не может быть приведен к java.lang.String.

4 ответа

Решение

The problem you're reporting is that

return (String)ob;

должно быть

return ob.toString();

если ob is never null; или же

return Objects.toString(ob);

if it might be.


But note that wrapping an object in an object to compare its toString() не обязательно Вы можете просто использовать Comparator<Object>, like Guava's Ordering.usingToString():

int order = Ordering.usingToString().compare(someObject, someOtherObject);

or whatever the Java 8 equivalent is. I guess it would be something like:

Comparator<Object> usingToString = (a, b) -> a.toString().compareTo(b.toString());
int order = usingToString(someObject, someOtherObject);

Концептуально это просто не имеет смысла!

Дело в том, что когда вы разрешаете произвольные типы объектов в вашем списке, тогда понятие "сортировка" здесь не имеет никакого смысла.

Таким образом, короткий ответ: забудьте об этом.

Технически, ваша проблема здесь:

return (String)ob;

Этот код предполагает, что obj является строкой. Но так как вы допускаете любой объект, это не обязательно так. Так obj.toString() предотвратит эту проблему во время выполнения, но; как сказал: решение этой технической проблемы не является реальным ответом.

Давайте вернемся к примеру из реального мира: предположим, вас просят отсортировать вещи на вашем столе: ложка, нож, чашка, банан, яблоко. Как вы собираетесь это сделать?

Если вообще, вы можете отказаться от чего-то общего; например, "вес". Таким образом, вы ставите все в масштабе; и использовать это, чтобы "отсортировать" их.

С точки зрения Java, единственное, что объединяет объекты, - это представление String (при вызове toString() на них) или числовое значение (при вызове hashCode()). Таким образом, вы можете "сортировать" по этим свойствам. Что бы сработало, но не привело ни к чему, даже отдаленно полезному.

Другими словами: когда вы намереваетесь отсортировать содержимое вашего списка, тогда нет другого пути, кроме как разрешить только "объекты такого же типа" в вашем списке. Вот почему коллекции Java работают именно так. В смысле: каждый использует дженерики, чтобы выразить это List<T> содержит объекты, которые имеют некоторый общий тип. С концептуальной точки зрения это просто означает: вместо того, чтобы что-либо попадать в определенный список, вы разрешаете только объекты, которые "имеют что-то общее".

Сортировка объектов без знания их типов не имеет смысла во многих случаях. Однако могут быть ситуации, когда вы хотите сгруппировать объекты по типу и т. Д. (Хотя для таких случаев лучше подойдет другой тип хранилища, например карта и т. Д.).

Проблема в том, что, не зная типов объектов, вы ограничены в том, что вы можете сделать. Ваш компаратор может сделать следующее, хотя:

  • Проверьте, реализуют ли сравниваемые объекты Comparable и позвонить compareTo() метод на одного.
  • Если они относятся к одному типу / классу, то они могут быть равными или нет (в зависимости от ваших требований). Как сравнить те, зависит от вас.
  • Если типы отличаются, вы можете попробовать сравнить по имени класса и т. Д.

При этом вам следует подумать о том, действительно ли вам это нужно, поскольку это трудно сделать с небольшой информацией, на которую вы можете положиться.

В Java и int это примитивный тип. Примитивные типы не имеют методов. Поэтому, когда вы делаете это.

b1.ob = 6;
b2.ob = 3;

Вы помещаете int в свой MyObject класс в своем ob переменная. в compareTo(Object current) метод, вы называете toString() метод на ob, Так как вы дали ob int, вы не можете вызывать какие-либо методы для него;

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