2010-01-26 50 views
1

我正在製作一款紙牌遊戲,其中紙牌被表示爲JLabels,具有在遊戲過程中更改的名稱和一些其他屬性。我想將平等定義爲簡單地比較兩張牌的全名(由字段fullName表示)。但是,這給我帶來的問題是我無法兩次添加相同的卡(因爲我在卡類中有其他字段可能不同)。等同於向JPanel添加組件的問題?

顯然,JPanel在後臺做了一些關於equals的檢查。然後,我唯一的id字段添加到每個卡,並在課堂上我保持一種我

private static Map<AbstractCard, Integer> idCount = new HashMap<AbstractCard, Integer>(); 

,然後每一個特定卡的構造函數被調用時創建的多少卡跟蹤我增加值在idCount。但是,如果我添加id以及原始name的支票,不僅地圖會中斷,而且如果名稱相同,它仍然不會添加多張卡片。這就是現在的方法:

/** 
* Compares this card to the specified object. The result is true if and only if 
* the argument is not null and is a Card object that represents the same full name 
* as this card. 
* @return true if the cards are equal, otherwise false 
*/ 
@Override 
public boolean equals(Object o) 
{ 
    if (!(o instanceof AbstractCard)) 
     return false; 
    else 
    { 
     AbstractCard c = (AbstractCard)o; 
     return this.fullName.equals(c.fullName) && this.id == c.id; 
    } 
} 

有關如何解決這個問題的任何想法?

編輯:我的hashCode返回fullName.hashCode()和在當前版本我加id

+0

你的意思是你的卡片擴展了'JLabel'? – 2010-01-26 17:46:25

+0

對,對不起,我在發佈問題後不久編輯了它。 – 2010-01-26 17:50:14

回答

2

編輯

我做了以下測試,它工作得很好:

private class MyLabel extends JLabel { 
    public MyLabel(String text) { 
     super(text); 
    } 
    public boolean equals(Object obj) { 
     return true; 
    } 
}; 


public MyPanel() { 
    getContentPane().setLayout(new GridLayout()); 
    getContentPane().add(new MyLabel("Label 1")); 
    getContentPane().add(new MyLabel("Label 2")); 
    getContentPane().add(new MyLabel("Label 3")); 
} 

,你面臨的問題是什麼?

BTW:這不會解決你的問題,但Java文檔equals

注意,一般需要覆蓋hashCode方法每當這個方法被覆蓋


如果一個卡擴展了JLabel,並且您爲每個卡創建了一個實例,您根本不應該覆蓋equals。確保不要將同一張卡片添加到兩個容器(或兩個容器)。這也不適用於真正的卡。

它可能是一種更好的方法來從他們的可視化分裂卡類。你有沒有考慮過沒有把你的卡從搖擺課程中擴展出來?

您可以覆蓋toString並將其顯示在JList中。

+0

我的意思是我可以創建兩個共享相同名稱的實例,但其他屬性不同。這兩張卡不是同一張卡片,但由於它們的名稱相同,我希望能夠將它們視爲「相同」。 我試過使用組合而不是繼承(實際上我的當前版本使用組合),但仍然有bug(功能?)在那裏 - 不能添加兩個以上相同的名稱。 – 2010-01-26 18:04:22

+0

我忘了提及hashCode,它已被添加到問題中。奇怪的是,當我做了和你的例子類似的東西時,它確實按照預期工作,但是當我在真正的代碼中完成時,有兩個「相等」卡加上兩個不同的(4個組件),我從getComponentCount ? – 2010-01-26 18:59:15

+0

聽起來像你還有其他一些問題。只要您能夠重現問題並查看導致此行爲的原因,就可以嘗試從程序中刪除內容。 – 2010-01-26 19:11:10

1

HashMaps依賴於哈希碼來查找正確的「桶」,然後通過相等性測試選擇正確的元素。如果你不重寫hashCode(),HashMap可能無法檢索該項目,即使它存在。一般來說,總是重寫equals()和hashCode()。

但是,我會敦促你重新考慮你的設計。這種引用計數不是一個好主意。另外,你在GUI代碼中混入了太多的邏輯和模型元素。你應該考慮採用更多的模型 - 視圖 - 控制器來解決問題。讓遊戲完全建模,然後讓UI代表模型。

0

我對此非常抱歉,這似乎一直是我自己的錯。經過大量調試和打印後,我發現我在另一個面板的一部分的面板中有參考,所以我不知何故只有「真正」有3張卡。在我刪除了參考資料並製作了一張新卡之後,它終於出現並返回了getComponentCount 4.

再次,我很抱歉浪費您的時間。

+1

猜猜我對''聽起來像你有其他問題然後'。:) – 2010-01-26 20:14:04

0

順便說一句,您可能喜歡讀這個簡單的game的來源。它根本不是一款紙牌遊戲,但是GameButton課程可能會提出一種使用Unicode字形來表示卡牌等級和套裝的方法。