2016-01-22 137 views
4

我有以下方法:比較Java中的兩個泛型類型?

public <U, V> boolean isEqual(List<U> a, List<V> b) { 
    // check if U == V 
} 

我要檢查,如果UV是相同的類。

+3

你爲什麼要這樣?你的用例是什麼?爲什麼不創建另一種具有單一類型「U」的方法?而如果'U'是'?延伸Something'? 「U == V」甚至意味着什麼? – Tunaki

+1

我正在創建一個方法來測試兩個對象的相等性。 第一個條件應該是他們的類型是一樣的 –

+0

我不明白這個的目的。你能否澄清一下細節,比如你想達到什麼目的? –

回答

7

你不能那樣做because of type erasure,就這麼簡單。

考慮以下幾點:

public static void main(String[] args) { 
    List<? extends Number> l1 = Arrays.asList(1L, 2, 3L); 
    List<? extends Number> l2 = Arrays.asList(1); 
    isEqual(l1, l2); 
} 

public static <U, V> boolean isEqual(List<U> a, List<V> b) { 
    // is U == V here? 
} 

U == V這裏? l1包含LongInteger實例,但l2包含單個Integer實例。


我從您的評論猜測:

第一個條件應該是他們的類型是相同的

那是你應該有,而不是一個單一類型U。在這種情況下,請使用以下簽名:

public static <U> boolean isEqual(List<U> a, List<U> b) { 

} 

並且因此,上述代碼將不再編譯。


什麼你也可以做的是加2個參數接受類:

public static <U, V> boolean isEqual(List<U> a, List<V> b, Class<U> uClass, Class<V> vClass) { 
    if (!uClass.equals(vClass)) { 
     // classes are different 
    } 
} 

在這種情況下,你可以打印一條消息,如果給定的類是不一樣的。

+0

我想給用戶發送兩種不同類型的靈活性,我想告訴他他們不是平等的。 –

+1

@MahmoudHanafy不幸的是,這是你無法做到的。 – Tunaki

+0

@Mahmoud而不是給他們發送兩種不同類型的靈活性,你說的是你想告訴他們的錯誤,爲什麼不簡單地不讓他們發送不同類型呢? –

0

不要依賴

a.getClass().equals(b.getClass()) 

這是不正確的,它只會檢查這兩個是否是ArrayList類型的,而不是字符串,整數等

試試這個只有

a.get(0).getClass().equals(b.get(0).getClass()) 

確保你檢查了null條件,否則你會在這裏遇到NullPointerException。

+0

這是比較兩個列表的第一個元素的運行時類型,而不是列表本身的類型參數。 –

-1

假設A和B是不爲空或不爲空,

a.get(0).getClass().equals(b.get(0).getClass()) 

應該做的伎倆。

+0

這與[本答案](http://stackoverflow.com/a/34951639/1743880)有何不同? – Tunaki

+0

這是比較列表的第一個元素的運行時類型,而不是列表的參數。如果兩個'List '不等於一個包含'Integer'而另一個包含'Double'。此外,如果一個'List '和'List '都包含一個'Double',那麼它們將是相等的。 –

2

如果您正在製作自己的類可以要求Class<T>包括在構造函數證明here

例:

public class SomeClass<T> { 

    private final Class<T> clazz; 

    public SomeClass(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    public Class<T> getParam() { 
     return clazz; 
    } 
} 

現在,您可以撥打SomeClass#getParam()得到Param類型聲明。


還有a way to do this with reflection.


這一切說,你所要做的怪異的變通來這樣做的原因是因爲Type Erasure。基本上在運行時Java看到所有的泛型爲Object,所以在編譯List時可能是List<Integer>List<Boolean>,但在運行時它們都是List<Object>

0

我想你想檢查== B的代替ü==五,在這種情況下,你是否有寫你自己的比較方法來比較類U和V的實例

1

如果您試圖比較兩個列表的內容,那麼你不應該自己實現類型比較。相反,你應該這樣做:

public static <U, V> boolean isEqual(List<U> a, List<V> b) { 
     if (a.size() != b.size()) 
      return false; 
     for (int i = 0; i < a.size(); i++) 
      if (!a.get(i).equals(b.get(i))) 
       return false; 
     return true; 
    } 

這樣你就可以依靠類型U和V能夠正確處理equals()。這裏有一些關於實現equals()的指導原則:http://www.javaworld.com/article/2072762/java-app-dev/object-equality.html

我猜你想要做的是在類型不同的情況下能夠快速返回。但是隨着我給你的實現,你會得到同樣的行爲 - 你會在第一次迭代時返回。