Как сравнить два объекта, не зная их типа
Я реализую класс отсортированного списка, в этом классе я собираюсь сортировать любые объекты, так что теперь я хочу проверить, является ли объект сопоставимым или нет,
я использовал этот код, чтобы переопределить метод 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, вы не можете вызывать какие-либо методы для него;