Java-объект Equality - PullRequest
       28

Java-объект Equality

0 голосов
/ 26 января 2010

Две карты с1 и с4 кажутся равными ... но они не почему. Я хочу, чтобы они были равны, чтобы в наборе был разрешен только один из них. : |

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);
 }
}

Ответы [ 8 ]

5 голосов
/ 26 января 2010

Прежде всего: вы назвали свой класс Card2, но везде называете его Card (включая метод equals(). Этот ответ предполагает, что вы заменяете все экземпляры Card2 на Card).

Вы определили equals() таким образом, чтобы вернуть true, если значение и тип карты совпадают.

c1 имеет значение 5 и тип Spade.

c4 имеет значение 5 и тип Spade.

Внешний вид для меня почти такой же.

2 голосов
/ 26 января 2010

Они равны (как только вы исправите опечатку, заменив Card2 на Card), ваша программа выведет:

true
Hearts 10
Spade 5

Что еще ты ожидал?

1 голос
/ 26 января 2010

Ваш метод 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());
}

То есть вы должны быть последовательны в использовании Карты и Карты2.

Также обратите внимание, что я изменил ваш:

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 . Причина, по которой это хорошая идея, заключается в том, что это усложняет код, поскольку вы говорите: «если что-то истинно, верните истину, иначе, если оно ложно, верните ложь». Вместо того, чтобы заставлять читателя кода работать над тем, что вы делаете, вы можете просто сказать «вернуть что-то», и конечный пользователь вашего кода сможет быстрее понять, что вы делаете.

1 голос
/ 26 января 2010

В чем проблема? Вывод в моей системе:

true
Spade 5
Hearts 10

Что, кажется, именно то, что вы хотите.

1 голос
/ 26 января 2010

Ваш hashCode() несовместим с equals().

java.util.HashSet использует hashCode. Вы должны реализовать hashCode(), чтобы учесть тип.

0 голосов
/ 06 сентября 2010

Вот наш хорошо полученный класс Card из недавнего проекта; надеюсь, это поможет вам. http://pastebin.com/qW41nwRE
«Состояние» используется для определения того, находится ли карта в колоде, в руке и т. Д. Значение составляет от 1 до 14, при этом 11–14 - это лицевые карты (Джек, Королева, Король и Туз).

0 голосов
/ 26 января 2010

Ваш метод equals нуждается в некоторых улучшениях. Вы должны проверить на ноль и сходство. Кроме того, использование instanceof может привести к тому, что equals станет некоммутативным, если вы разрешите создание подклассов и реализует equals в обоих классах. Например, если Card2 расширяет Card, и у Card есть равные, которые проверяют экземпляр Card, и Card2 переопределяет это с помощью равных, проверяющих экземпляр Card2, то для экземпляра cc2 класса Card2 и другого экземпляра cc Card используется instanceof означает что cc.equals (cc2) имеет значение true, а cc2.equals (cc) - false, что может привести к нежелательному поведению.

Вы можете сделать следующее:

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 должен искать только экземпляр 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;
} 

Опять же, все это может быть совершенно не связано с вашей проблемой.

0 голосов
/ 26 января 2010

В вашем методе 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());
}
...