[英]How to compare two objects without knowing their type
我正在實現一個排序列表類,在該類中,我將對任何類型的對象進行排序,因此現在我想測試對象是否可比較,
我用這段代碼來覆蓋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));
}
}
但它總是給我這個例外:
線程“主”中的異常java.lang.ClassCastException:java.lang.Integer無法轉換為java.lang.String
從概念上講,這根本沒有道理!
關鍵是:當您允許列表中包含任意類型的對象時,此處的“排序”概念毫無意義。
因此,簡短的答案是:忘記它。
從技術上講,您的問題在這里:
return (String)ob;
該代碼假定 obj是一個字符串。 但是,考慮到任何對象,這不一定是正確的。 因此obj.toString()
可以避免該運行時問題,但是; 如前所述:解決技術問題並不是真正的答案。
讓我們回到一個真實的例子:假設要求您對桌上的東西進行排序:湯匙,刀子,杯子,香蕉,蘋果。 您打算如何做?
如果有的話,您可以撤消所有共同點。 例如“重量”。 因此,您將所有事物都按比例放置; 並用它來“排序”它們。
從Java的角度來看,對象唯一的共同點是String表示形式(在它們上調用toString()
時)或數值(在調用hashCode()
)。 因此,您可以對這些屬性進行“排序”。 這將起作用,但不會產生任何遠程有用的結果。
換句話說:當您打算對列表的內容進行排序時,別無選擇,只能在列表中允許“相同類型的對象”。 這就是java集合完全以這種方式工作的原因。 從某種意義上說:人們使用泛型來表示List<T>
包含具有某種公共類型的對象。 從概念的角度來看,這僅意味着:不允許任何東西進入特定列表,而只允許“具有某些共同點”的對象。
您要報告的問題是
return (String)ob;
應該
return ob.toString();
如果ob
永不為null; 要么
return Objects.toString(ob);
如果可能的話。
但是請注意, toString()
將對象包裝在對象中以比較其toString()
。 您可以簡單地使用Comparator<Object>
,例如Guava的Ordering.usingToString()
:
int order = Ordering.usingToString().compare(someObject, someOtherObject);
或任何與Java 8等效的東西。 我猜可能是這樣的:
Comparator<Object> usingToString = (a, b) -> a.toString().compareTo(b.toString());
int order = usingToString(someObject, someOtherObject);
在許多情況下,在不知道對象類型的情況下對對象進行排序是沒有意義的。 但是,在某些情況下,您可能希望按類型等對對象進行分組。(盡管其他類型的存儲(如地圖等)可能更適合此類情況)。
問題在於,在不知道對象類型的情況下,您只能做些什么。 您的比較器可以執行以下操作:
Comparable
並在其上調用compareTo()
方法。 話雖如此,您應該真正考慮您是否真正需要它,因為很難依靠您可以依靠的少量信息。
在Java中,int是原始類型。 基本類型沒有方法。 因此,當您執行此操作時。
b1.ob = 6;
b2.ob = 3;
您正在將一個int放入其ob
變量的MyObject
類中。 在compareTo(Object current)
方法中,對ob
調用toString()
方法。 由於您給ob
了一個int值,因此您無法在其上調用任何方法 ;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.