【问题标题】:ContainsAll array list issue JavaContainsAll 数组列表问题 Java
【发布时间】:2016-01-16 15:52:34
【问题描述】:

所以我尝试使用 containsAll 内置列表方法来比较两个数组

我对单个值使用了 contains 方法,它工作得很好,但是 contains all 却不行。

我正在做一个纸牌游戏,所以我正在检查一组卡片是否也在另一组卡片中

所以:

  if(this.hand.containsAll(hand.getCards())){

但是这个语句一直返回 false..

这是构造函数

  private ArrayList<Card> hand;
     public Hand(ArrayList<Card> hand) {
            this();
            this.hand.addAll(hand);
        }

这是获取卡片的方法

 public ArrayList<Card> getCards() {
        return this.hand;
    }

不确定为什么这段代码没有为 containsAll 返回 true,但单独完成时很好,是否有一些我没有考虑过的常见概念?

任何指针都会是一个奖励

谢谢

编辑:

使用时返回 true :

作品

public boolean hasCard(Card card){
   if (this.hand.contains(card)){
       return true;
   }
}

没有

public boolean hasCards(Hand hand){
    if(this.hand.containsAll(hand.getCards()){
    return true
}
}

主要..

    Card one = new Card(Card.Rank.ACE, Card.Suit.CLUBS);
            Card two = new Card(Card.Rank.ACE, Card.Suit.DIAMONDS);
            Card three = new Card(Card.Rank.TWO, Card.Suit.SPADES);
            Card four = new Card(Card.Rank.SIX, Card.Suit.randSuit());
            Card five = new Card(Card.Rank.SEVEN, Card.Suit.randSuit());
            ArrayList<Card> cards = new ArrayList<>();
            cards.add(one);
            cards.add(two);
            cards.add(three);
            cards.add(four);
            cards.add(five);
            Hand h = new Hand(cards);


   Card ones = new Card(Card.Rank.ACE, Card.Suit.CLUBS);
        Card twos = new Card(Card.Rank.ACE, Card.Suit.DIAMONDS);
        Card threes = new Card(Card.Rank.TWO, Card.Suit.SPADES);
        ArrayList<Card> cards2 = new ArrayList<>();

// works
h.hasCard(five);

// doesn't
h.hasCards(h2);


        cards2.add(ones);
        cards2.add(twos);
        cards2.add(threes);
        Hand h2 = new Hand(cards2);

【问题讨论】:

  • this.handHand 还是 List&lt;Card&gt; 实例?
  • List 实例@Tunaki
  • 你在Card类中实现了equals方法吗?
  • 不,@yole 先生,这是我应该避免或做的事情吗?
  • 不是一回事,所以我用这个。 @Dima,这个。指的是对象值,而 hand.getCards() 指的是参数中传递的手值.. 这只是基本的 java

标签: java arrays list


【解决方案1】:

试试这个h.hasCard(new Card(Card.Rank.ACE, Card.Suit.CLUBS))。它填充返回false。但是这个 h.hasCard(one) 返回 true。

要了解原因,试试这个:one.equals(new Card(Card.Rank.ACE, Card.Suit.CLUBS)。这是同一张卡的两个实例,但是java无法知道它。它们是两个不同的对象。

您已将one 添加到您的h 手上,因此,在查找该对象时,您会找到它。但是搜索另一个对象new Card(Card.Rank.ACE, Card.Suit.CLUBS) 失败,因为java 不知道它代表同一张卡片。

要解决此问题,您必须覆盖 Card 上的 equals 消息,并使其对对应于同一张卡的对象返回 true。

您的containsAll 调用因同样的原因不起作用:手牌包含所有牌,但它们由不同的对象表示。实现equals 方法也可以解决这个问题。

【讨论】:

  • 请问是我的构造函数 public Hand(ArrayList hand) { this(); this.hand.addAll(hand); } 一个好方法吗?
  • “一个好方法” ... 什么?初始化手?没关系...我将参数声明为ListCollection,而不是ArrayList:经验法则是始终使用适合您目的的最抽象的接口级别。
  • 这样你就有了 this.hand = new List();
  • 不,你可以实例化List,它是一个接口。我说的是构造函数参数类型,而不是实现。
【解决方案2】:

您需要重写equals 方法。

当你这样做时:

Card five = new Card(Card.Rank.SEVEN, Card.Suit.randSuit());
h.hasCard(five);

您实际上是在检查(five == five),这是真的。这是因为equals()方法的默认实现是(来自doc):

Object 类的 equals 方法实现了对象上最有区别的可能等价关系;也就是说,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象(x == y 的值为 true)时,此方法才返回 true。

现在,当您拥有包含以下卡片的 h2 时:

Card ones = new Card(Card.Rank.ACE, Card.Suit.CLUBS);
Card twos = new Card(Card.Rank.ACE, Card.Suit.DIAMONDS);
Card threes = new Card(Card.Rank.TWO, Card.Suit.SPADES);

h以下卡片:

    Card one = new Card(Card.Rank.ACE, Card.Suit.CLUBS);
    Card two = new Card(Card.Rank.ACE, Card.Suit.DIAMONDS);
    Card three = new Card(Card.Rank.TWO, Card.Suit.SPADES);
    Card four = new Card(Card.Rank.SIX, Card.Suit.randSuit());
    Card five = new Card(Card.Rank.SEVEN, Card.Suit.randSuit());

然后你做:

h.hasCards(h2);

然后您实际上是在检查ones, twos and threes 是否存在于h 中。这是错误的,因为例如 onesNOT == h 中的任何对象。

您可以通过打印(ones == one) 的值自行检查,这将是错误的。

解决方案:

如果您在 Card 类中覆盖 equals() 方法,则类似于:

@Override
public boolean equals(Object o) {

    // Check if o == itself  
    if (o == this) {
        return true;
    }

    // Check to see if o is instance of Card or not
    if (!(o instanceof Card)) {
        return false;
    }

    // typecast o to Card to compare 
    Card c = (Card) o;

    // check equality (assuming Rank and Suit to be int, else you need to change equality condition here)
    return this.Rank == c.Rank
            && this.Suit == c.Suit;
}

【讨论】:

  • 我使用枚举的事实会是个问题吗?同样,Complex 也没有显示给我@Atri
  • @session_start 对不起,我使用的是 equals 模板。
  • @session_start 比较枚举检查这个:stackoverflow.com/questions/1750435/…
  • 不使用 c 时,卡片 c= (Card) o 的意义何在? @Atri
猜你喜欢
  • 1970-01-01
  • 2013-03-17
  • 2013-04-28
  • 2012-11-11
  • 1970-01-01
  • 2021-07-19
  • 2017-07-09
  • 2012-02-12
相关资源
最近更新 更多