0

I have an class called Record that consists of a vector of Data class objects.

Class Data has nothing but two fields:

Object value;
String name;

I override the equals method in the Record class as follows:

public boolean equals(Object obj) {
    boolean check = true;
    for (int i = 0; i < this.columnsOfData.size();i++) {
        System.out.println( ((Record) obj).columnsOfData.get(i).name + " OBJECT " + ((Record) obj).columnsOfData.get(i).value );
        System.out.println( columnsOfData.get(i).name + " THIS " + columnsOfData.get(i).value );
        if( !((((Record) obj).columnsOfData.get(i).name).equals(this.columnsOfData.get(i).name))   || !((((Record) obj).columnsOfData.get(i).value).equals(this.columnsOfData.get(i).value))) {
            check = false;
        }
    }
    
    return (obj instanceof Record && check);
}

I initialize HashSet as follows:

Set<Record> answer = new HashSet<Record>()

and start testing

        Record r1 = new Record();
        r1.columnsOfData.add(new Data(new Double( 1.5 ),"gpa"));
        r1.columnsOfData.add(new Data(new String("John"),"name"));
        r1.columnsOfData.add(new Data(new Integer( 2 ),"id"));
        
        Record r2 = new Record();
        r2.columnsOfData.add(new Data(new Double( 1.5 ),"gpa"));
        r2.columnsOfData.add(new Data(new String("John"),"name"));
        r2.columnsOfData.add(new Data(new Integer( 2 ),"id"));

        System.out.println(r1.equals(r2)); //RETURNS TRUE
        answer.add(r1);
        System.out.println(answer.contains(r2)); //RETURNS FALSE

Any help understanding where the issue is would be greatly appreciated.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
HR1
  • 487
  • 4
  • 14
  • 1
    Also you also overriding `hashCode`? – Jacob G. Apr 06 '20 at 18:56
  • @JacobG.No No I'm not, I'm not quite sure why I'm supposed to do that, or how to implement it exactly – HR1 Apr 06 '20 at 18:59
  • It could be that your 2 objects are equal, but they are not the same instance. – ThallsEternal Apr 06 '20 at 19:00
  • @ThallsEternal how do I go around fixing that? – HR1 Apr 06 '20 at 19:01
  • You could create another class that inherits from List<> (or whatever datatype answer is) and then override the contains method when accepting an object of type Record – ThallsEternal Apr 06 '20 at 19:04
  • See https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java – PM 77-1 Apr 06 '20 at 19:05
  • 1
    The `obj instanceof Record` should be the *first* thing to check, not the last thing. Most notably, it should happen before you are performing the `(Record) obj` type casts. Besides that, use neither, `new Double( 1.5 )`, `new String("John")`, nor `new Integer( 2 )`. Use `1.5`, `"John"`, and `2`. The actual problem has been explained already, without a proper `hashCode()` implementation, you can’t use `HashSet`. – Holger Apr 07 '20 at 10:28

2 Answers2

1

Try to override also the hashCode method. It should work. You can find an explanation here: HashSet contains() method

0

HashSet relies on the contract that hashCodes of equal objects are equal. That is, if a.equals(b) returns true, then a.hashCode() must be the same as b.hashCode()

You should override the hashCode() method of Record to use it in a HashSet

sparik
  • 1,181
  • 9
  • 16