【问题标题】:Equals method override messes up other code/changes output?等于方法覆盖会弄乱其他代码/更改输出吗?
【发布时间】:2023-01-13 03:14:20
【问题描述】:

我正在为学校项目制作纸牌游戏。我需要我的 equals 方法能够正确地告诉我一张卡是否与另一张卡具有相同的等级。但是,我注意到只要等于重写存在,即使我不对任何东西使用“.equals()”,它似乎也会搞砸其他代码的输出。这是我的输出示例,其中 equals 方法处于活动状态:

Player 1
Has spoon? false
Is dealer? true
Hand: [7 of Clubs, 2 of Clubs, 8 of Spades, 8 of Clubs]
Dealer: 
Your dealer has a deck of 48 cards: 

Cards currently in deck: 3 of Hearts, 4 of Hearts, 5 of Hearts, 6 of Hearts, 9 of Hearts, 10 of Hearts, Jack of Hearts, Queen of Hearts, King of Hearts, Ace of Hearts, 2 of Spades, 3 of Spades, 4 of Spades, 5 of Spades, 6 of Spades, 7 of Spades, 9 of Spades, 10 of Spades, Jack of Spades, Queen of Spades, King of Spades, Ace of Spades, 2 of Clubs, 3 of Clubs, 4 of Clubs, 5 of Clubs, 6 of Clubs, 7 of Clubs, 8 of Clubs, 9 of Clubs, 10 of Clubs, Jack of Clubs, Queen of Clubs, King of Clubs, Ace of Clubs, 2 of Diamonds, 3 of Diamonds, 4 of Diamonds, 5 of Diamonds, 6 of Diamonds, 7 of Diamonds, 8 of Diamonds, 9 of Diamonds, 10 of Diamonds, Jack of Diamonds, Queen of Diamonds, King of Diamonds, Ace of Diamonds

我可以创建多个玩家并给他们每人发一定数量的牌。

在某些情况下,玩家会收到重复的牌,这是一个明显的问题。最重要的是,它不会从牌组中移除正确的牌,有时会移除正确的等级但移除错误的花色。请注意,该玩家手中的一些牌仍在牌组中,但取出了几张红心牌。

这是注释掉 equals 方法的输出,没有其他改变:

Player 1
Has spoon? false
Is dealer? true
Hand: [7 of Diamonds, Queen of Hearts, 6 of Diamonds, King of Spades]
Dealer: 
Your dealer has a deck of 48 cards: 

Cards currently in deck: 2 of Hearts, 3 of Hearts, 4 of Hearts, 5 of Hearts, 6 of Hearts, 7 of Hearts, 8 of Hearts, 9 of Hearts, 10 of Hearts, Jack of Hearts, King of Hearts, Ace of Hearts, 2 of Spades, 3 of Spades, 4 of Spades, 5 of Spades, 6 of Spades, 7 of Spades, 8 of Spades, 9 of Spades, 10 of Spades, Jack of Spades, Queen of Spades, Ace of Spades, 2 of Clubs, 3 of Clubs, 4 of Clubs, 5 of Clubs, 6 of Clubs, 7 of Clubs, 8 of Clubs, 9 of Clubs, 10 of Clubs, Jack of Clubs, Queen of Clubs, King of Clubs, Ace of Clubs, 2 of Diamonds, 3 of Diamonds, 4 of Diamonds, 5 of Diamonds, 8 of Diamonds, 9 of Diamonds, 10 of Diamonds, Jack of Diamonds, Queen of Diamonds, King of Diamonds, Ace of Diamonds, 

我相信这会完美无缺。玩家获得他们的特定卡牌,这些卡牌将从牌组中移除。

这是我的等于方法:

public boolean equals(Object obj) {
        if (!(obj instanceof Card)){
            return false;
        } else {
            Card card = (Card) obj;
            return card.cardNum == this.cardNum;
        }
    }

我猜这一定是在卡片从牌组中移除时发生的,而不是在它们被创建时发生的,因为即使使用 equals 方法,牌组仍然由 52 个单独的独特卡片对象组成。

所以,我使用 2 种方法从一副牌中取出一张牌:deal 和 deals

    /**
     * @return randomCard, the randomly selected card
     */
    public Card deal() {
        Random rand = new Random();
        Card randomCard;

        randomCard = m_cards.get(rand.nextInt(m_cards.size()));
        m_cards.remove(randomCard);

        return randomCard;
    }
    /**
     * @param n, the number of times deal is called
     * @return cardsDealt, a LinkedList containing the cards removed from the Deck.
     */
    public LinkedList<Card> deals(int n) {
        LinkedList<Card> cardsDealt = new LinkedList<Card>();

        for(int i = 0; i < n; i++) {
            cardsDealt.add(m_deck.deal());
        }
        // System.out.print("\nRemoving: ");
        return cardsDealt;
    }

这是我现在拥有的 Player 类代码:

import java.util.LinkedList;
public class Player {
    private int playerNum;
    private boolean hasSpoon;
    private boolean isDealer;

    static Dealer dealer = new Dealer();
    LinkedList<Card> hand;

    public Player(int playerNum) {
        this.playerNum = playerNum;
        this.hasSpoon = false;
        if(this.playerNum == 1) {
            this.isDealer = true;
        }
        this.hand = new LinkedList<Card>(dealer.deals(4));
    }

    public String toString() {
        return "\nPlayer " + playerNum + 
               "\nHas spoon? " + hasSpoon + 
               "\nIs dealer? " + isDealer + 
               "\nHand: " + hand
              + "\nDealer: " + dealer;
    }

    public static void main(String[] args) {
        Player player1 = new Player(1);

        System.out.println(player1);
    }
}

同样,这是针对学校的,所以不要直接给我答案,但我很想知道为什么会这样,并指出正确的方向。

【问题讨论】:

  • cardNum 是什么?你需要展示你的Card 类。
  • 顺便说一句,在覆盖equals 时始终覆盖hashCode——但在这种情况下不会造成任何问题。
  • 哦:“我需要我的 equals 方法才能正确地告诉我一张牌是否与另一张牌具有相同的等级”如果您认为黑桃 A 和梅花 A 是同一张牌,那么您的代码的行为如下预期的。
  • 因为 equalsList.remove 用来决定移除哪一项。
  • Card上写另一个方法:boolean hasSameRankAs(Card otherCard)而不是破坏equals的语义。

标签: java oop equals


【解决方案1】:
public Card deal() {
    Random rand = new Random();
    Card randomCard;

    randomCard = m_cards.get(rand.nextInt(m_cards.size()));
    m_cards.remove(randomCard);

    return randomCard;
}

m_cards.remove(randomCard) – 想想这个方法如何知道要从集合中删除哪张卡片?准确的说,它调用equals 参数和集合中的每一项!

此方法的规范实现是(或多或少):

public boolean remove(Object o) {
    Iterator<E> it = iterator();
    while (it.hasNext()) {
        if (Objects.equals(o, it.next())) {
            it.remove();
            return true;
        }
    }
    return false;
}

PS Random 实例应该被缓存,而不是在你每次需要它们的时候用new重新创建。如果这样做,您将无法获得良好的随机值,甚至可能连续多次得到相同的数字。

【讨论】:

    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 2014-12-31
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多