[英]Compare two generic types in Java?
我有以下方法:
public <U, V> boolean isEqual(List<U> a, List<V> b) {
// check if U == V
}
我想檢查U
和V
是否是相同的類。
你不能因為類型擦除而這樣做,就這么簡單。
考慮以下:
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
包含Long
和Integer
實例,但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
}
}
在這種情況下,如果給出的類不相同,則可以打印消息。
如果您正在制作自己的類可以要求Class<T>
包含在構造函數證明這里
例如:
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()
來獲取聲明的類型參數。
所有這些都說,你必須做一些奇怪的解決方法是因為Type Erasure 。 基本上在運行時,Java將所有泛型視為Object
,因此編譯List
可能是List<Integer>
或List<Boolean>
,但在運行時它們都是List<Object>
。
如果您嘗試比較兩個列表的內容,則不應自行實現類型比較。 相反,你應該這樣做:
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
我猜你想要做的是能夠在類型不同的情況下快速返回。 但是通過我給你的實現,你會得到相同的行為 - 你會在第一次迭代時返回。
不要依賴
a.getClass().equals(b.getClass())
這是不正確的,它只會檢查兩者是否為ArrayList類型而不是String,Integer等。
試試這個
a.get(0).getClass().equals(b.get(0).getClass())
確保檢查null條件,否則在這里會遇到NullPointerException。
我想你想檢查a == b而不是U == V.在這種情況下,你必須編寫自己的比較方法來比較U和V類的實例。
假設a和b不為null且不為空,
a.get(0).getClass().equals(b.get(0).getClass())
應該做的伎倆。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.