-2

两张牌 c1 和 c4 似乎是相等的……但它们不是为什么。我希望它们相等,以便集合中只允许其中一个。:|

import java.util.*;
class Card2
{
 private int value;
 private String type;

 public Card2(int v,String t)
 {
  value=v;
  type=t;
 }

 public int getValue()
 {
  return value;
 }

 public String getType()
 {
  return type;
 }

 public String toString()
 {
  return(type+" "+value);
 }

 public boolean equals(Object oo)
 {
  if(!(oo instanceof Card))
  return false;

  Card cc=(Card) oo;

  if(this.getValue()==cc.getValue() && this.getType().equals(cc.getType()))
  return true;
  else
  return false;
 }

 public int hashCode()
 {
  return value;
 }

 public static void main(String args[])
 {
  HashSet<Card> deck=new HashSet<Card>();

  Card c1=new Card(5,"Spade");

  Card c2=new Card(10,"Hearts");

  Card c3=c2; //Equal Ref card entity

  Card c4=new Card(5,"Spade");

  System.out.println(c1.equals(c4));

  deck.add(c1);
  deck.add(c2);
  deck.add(c4);
  deck.add(c3);

  for(Card cc:deck)
  System.out.println(cc);
 }
}
4

8 回答 8

5

First of all: you called your class Card2 but refer to it as Card everywhere (including the equals() method. This answer assumes you replace all instances of Card2 with Card).

You defined equals() in a way to return true if the value and the type of the card to be the same.

c1 has a value of 5 and a type of Spade.

c4 has a value of 5 and a type of Spade.

The look pretty much the same to me.

于 2010-01-26T12:59:14.783 回答
2

They are equal (once you fix the typo by replacing Card2 by Card), your program output is:

true
Hearts 10
Spade 5

What else did you expect?

于 2010-01-26T12:58:59.963 回答
1

Your hashCode() is inconsistent with equals().

java.util.HashSet uses hashCode. You should implement hashCode() to take the type into account.

于 2010-01-26T12:57:44.577 回答
1

你的 equals() 方法是错误的,试试这个:

public boolean equals(Object oo)
{
  if(!(oo instanceof Card2))
    return false;

  Card2 cc=(Card2) oo;

  return this.getValue()==cc.getValue() && this.getType().equals(cc.getType());
}

也就是说,您应该在使用 Card 和 Card2 时保持一致。

另请注意,我更改了您的:

if(this.getValue()==cc.getValue() && this.getType().equals(cc.getType()))
  return true;
else
  return false;

return this.getValue()==cc.getValue() && this.getType().equals(cc.getType());

因为这更短,并且避免违反checkstyle 规则。这是一个好主意的原因是它使代码复杂化,因为您所说的是“如果某事为真,则返回真,否则如果为假,则返回假”。与其强迫代码的读者弄清楚你在做什么,你可以简单地说“返回一些东西”,你的代码的最终用户可以更快地理解你在做什么。

于 2010-01-26T13:23:21.077 回答
1

问题是什么?我的系统上的输出是:

true
Spade 5
Hearts 10

这似乎正是你想要的。

于 2010-01-26T13:00:50.810 回答
0

您的 equals 方法需要一些改进。您应该测试 null 和相同性。此外,如果您允许子类化并在两个类中实现 equals,则使用 instanceof 可能会导致 equals 变得不可交换。例如,如果 Card2 扩展 Card,并且 Card 有一个测试 instanceof Card 的等号,并且 Card2 用测试 instanceof Card2 的等号覆盖它,那么对于 Card2 类的一个实例 cc2 和 Card 的另一个实例 cc,使用 instanceof 意味着cc.equals(cc2) 为真,但 cc2.equals(cc) 为假,这可能导致不良行为。

您可以执行以下操作:

public boolean equals(Object other) {
    // null is not equal
    if (null == other)
        return false;
    // same is equal
    if (this == other)
        return true;
    // different class, not equal
    if (other.getClass() != getClass())
        return false;

或者,如果您想允许子类化,您应该只测试超类中的属性。因此,如果 Card 具有值,并且 Card2 扩展 Card 并且具有值和类型,那么您的 equals 方法应该只查找 instanceof Card 并只比较 Card 的属性:

    //if (other.getClass() != getClass())
    //    return false;
    if (!(other instanceof Card))
        return false;
    card = (Card) other;
    if (this.getValue() == card.getValue())
        return true;
    return false;
} 

再说一次,所有这些可能与您的问题完全无关。

于 2010-01-26T15:01:46.600 回答
0

您的 equals() 方法缺少另一个相等性检查。检查对象本身是否是相同的引用。当你比较“c2.equals(c3)”之类的东西时,这是一个短路。

public boolean equals(Object oo)
{
  if(!(oo instanceof Card2))
    return false;

  if(this == oo) //comparing an object to itself is equal
    return true;

  Card2 cc=(Card2) oo;

  return this.getValue()==cc.getValue() && this.getType().equals(cc.getType());
}
于 2010-01-26T14:43:16.790 回答
0

这是我们最近一个项目中广受好评的卡片课程;希望它会帮助你。 http://pastebin.com/qW41nwRE
“状态”用于确定卡片是否在牌组中,是否在手等。值从 1 到 14,其中 11 - 14 是面牌(Jack,Queen 、国王和王牌)。

于 2010-09-05T21:29:01.973 回答