簡體   English   中英

如何在不知道對象類型的情況下比較兩個對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM