2016-01-21 59 views
3

我有一個任務來實現一個通用的Pair接口,它代表像(x,y)這樣的有序對。我正在嘗試編寫equals方法,但我必須將該參數設置爲一個普通對象而不是一對,所以我不知道如何獲取它的座標。當我嘗試編譯時,由於Object類沒有fst和snd方法,所以我得到了一個未找到符號的錯誤。我應該拋出一個異常還是什麼?注意:我的教授給了我們一個模板,我只是在填寫方法,我不認爲我被允許改變參數或方法。不能使用方法?

下面是相關的代碼:

public class Pair<T1,T2> implements PairInterface<T1,T2> 
{ 
private T1 x; 
private T2 y; 

public Pair(T1 aFirst, T2 aSecond) 
{ 
    x = aFirst; 
    y = aSecond; 
} 

/** 
* Gets the first element of this pair. 
* @return the first element of this pair. 
*/ 
public T1 fst() 
{ 
    return x; 
} 

/** 
* Gets the second element of this pair. 
* @return the second element of this pair. 
*/ 
public T2 snd() 
{ 
    return y; 
} 

...

/** 
* Checks whether two pairs are equal. Note that the pair 
* (a,b) is equal to the pair (x,y) if and only if a is 
* equal to x and b is equal to y. 
* @return true if this pair is equal to aPair. Otherwise 
* return false. 
*/ 
public boolean equals(Object otherObject) 
{ 
    if(otherObject == null) 
    { 
     return false; 
    } 

    if(getClass() != otherObject.getClass()) 
    { 
     return false; 
    } 
    T1 a = otherObject.fst(); 
    T2 b = otherObject.snd(); 
    if (x.equals(a) && y.equals(b)) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

這是我得到的錯誤:

類比較後
./Pair.java:66: cannot find symbol 
    symbol : method fst() 
    location: class java.lang.Object 
    T1 a = otherObject.fst(); 
        ^
    ./Pair.java:67: cannot find symbol 
    symbol : method snd() 
    location: class java.lang.Object 
    T2 b = otherObject.snd(); 
        ^
+4

在https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html中閱讀有關投射的部分。坦率地說,我很驚訝你的老師讓你使用泛型,如果你還不知道如何施放,這是一件非常複雜的事情。而且,如果你使用'first'和'second'而不是'fst'和'snd',你的代碼將會非常可讀。 –

+0

一旦建立實際的對象類型,您將需要執行顯式轉換。 –

+0

你必須將另一個物體成爲一對,第一個'對 otherPair =(對)otherObject;'。 – EpicPandaForce

回答

0

if(getClass() != otherObject.getClass()) return false;

你需要ŧ o創建新的變量與正確的類型,就像這樣:

Pair<T1,T2> pair = (Pair<T1,T2>)otherObject; 

,那麼你就可以調用其方法之前,使用pair及其方法

+1

你真的可以做''嗎?還是他們應該使用''?我現在正在考慮這個問題,但我不確定。 – EpicPandaForce

+0

@EpicPandaForce你可以同時使用,我更喜歡投到T1,T2 –

0

投下你otherObject一對。

Pair<T1, T2> otherPair = (Pair) otherObject; 
T1 a = otherPair.fst(); 
T2 b = otherPair.snd(); 
0

這是因爲你不先投出otherObject,所以JVM認爲它是Object類型的。一個對象沒有方法fst()和snd(),所以它失敗了。

爲了解決,鑄otherObject配對然後調用FST()和snd():

public boolean equals(Object otherObject) 
{ 
    if(otherObject == null) 
    { 
     return false; 
    } 

    if(getClass() != otherObject.getClass()) 
    { 
     return false; 
    } 


    T1 a = ((Pair<T1, T2>)otherObject).fst(); 
    T2 b = ((Pair<T1, T2>)otherObject).snd(); 
    if (x.equals(a) && y.equals(b)) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 
4

equals方法的參數是一個Object,這是不保證有你的方法fstsnd,因此編譯器錯誤。爲了能夠調用這些方法,您需要有一個Pair對象。

標準做法是測試傳入的對象的類別,以查看它是否與this屬於同一類別,如果它不是同一類別,則返回false。通常這是用instanceof完成的,然後是true。該轉換允許編譯器將對象視爲您所說的類。這允許編譯器找到你想調用的方法。

if(otherObject == null) 
{ 
    return false; 
} 

// Use instanceof 
if(!(otherObject instanceof Pair)) 
{ 
    return false; 
} 
// Cast - use <?, ?>; we don't know what they are. 
Pair<?, ?> otherPair = (Pair<?, ?>) otherObject; 
Object a = otherPair.fst(); 
Object b = otherPair.snd(); 
// Simplified return 
return (x.equals(a) && y.equals(b)); 
+1

我想你的意思是!(otherObject instanceof Pair)返回false ...? – Idos

+0

與'getClass()'方法不同的是,這個方法允許子類。如果語句「如果它不是同一類,則返回false」是不正確的。請注意這一點。 – bcsb1001

+1

@Idos更正。 – rgettman

0

你保證以後getClass() != otherObject.getClass()是真的,你可以執行安全投給Pair<?, ?> pair = (Pair<?, ?>) otherObject;。然後,按原樣使用您的代碼。 注意:您不能執行安全轉換爲Pair<T1, T2>,因爲您只知道otherObject是Pair<?, ?>的實例。但是,與.equals()的比較仍然可以正常工作。

+0

注意:您可以執行安全轉換對,因爲在運行期間它們實際上只是對象 –

+0

@Lashane在運行時,它實際上是「Pair」。而且,雖然這個演員是合法的,但這是不好的做法。它可能不是'Pair ',所以稱它爲不是一個好主意。 – bcsb1001

+0

實際上鑄造對象是不好的做法,特別是如果T是'T extends SomeInterface'' –

0

你必須明確地將另一個對象強制轉換爲一對(首先考慮到你已經知道它是一個Pair對象,因爲類是相同的),但是你不知道它是什麼類型,所以你應該使用通配符。

Pair<?, ?> otherPair = (Pair<?, ?>)otherObject; 
//add null-checks if fst() or snd() is nullable 
if(this.fst().equals(otherPair.fst()) && this.snd().equals(otherPair.snd()) { 
    return true; 
} else { 
    return false; 
} 
+0

構造函數'if(foo)return true;否則返回false;'可能被簡化爲'return foo;'。 – bcsb1001

+0

@ bcsb1001是的,我剛剛認爲這是第一眼看起來更清潔。 – EpicPandaForce

0

您可以將任何對象類型傳遞給equals(),因此正確實現equals的一部分是檢查參數Object的類型。

如果你看看java核心類,他們通常首先檢查==,然後是否是實現equals()的類的實例。

一般來說,您應該檢查: 1)==相等,即參數是否是對當前對象本身的引用 - 如果是,則對象應該等於每個equals()。這在計算上便宜。 2)參數是否爲空。這在計算上也便宜,如果爲真,則確保equals()返回false。 3)參數對象是否是當前對象類的一個實例。如果不是這樣,它不可能是平等的,並且演員將無法勝任。 4)然後投它,並開始比較各部分彼此

懶惰的程序員tip-eclipse可以使用嚮導自動生成漂亮的java equals()塊。它在右鍵單擊>源>生成hashcode()equals()和bam,它會生成一個適當的equals()方法。