java - hashCode changes each time the object is created -


there escapes me hashcode. know if override equals, must override hashcode too. know if 2 objects equal, hashcode of 2 objects must equal. if fields checked in equals method don't change, hashcode should not change, right?

if so, can't understand why each time create instance of object below, different hashcode:

public class effect {      private long timestamp;     private int damage;     private squaretype squaretype;      public effect(long timestamp, int damage, squaretype squaretype) {         this.timestamp = timestamp;         this.damage = damage;         this.squaretype = squaretype;     }      public long gettimestamp() {         return timestamp;     }      public int getdamage() {         return damage;     }      public squaretype getsquaretype() {         return squaretype;     }      @override     public boolean equals(object o) {         if (this == o) return true;         if (o == null || getclass() != o.getclass()) return false;          effect effect = (effect) o;          if (getdamage() != effect.getdamage()) return false;         return getsquaretype() == effect.getsquaretype();     }      @override     public int hashcode() {         int result = getdamage();         result = 31 * result + (getsquaretype() != null ? getsquaretype().hashcode() : 0);         return result;     }      @override     public string tostring() {         string ret = "effect hashcode: " + hashcode();         return ret;     } } 

in code create kind of objects continuously on time. field changes each time "timestamp", 2 other fields don't change (unless there specific event). happens hashcode value different, if "damage" , "squaretype" same. don't use "timestamp" in equals , hashcode, can't understand why behavior.

update

this squaretype:

public enum squaretype {     fire, wind, water, earth } 

update 2

for example, if create 10 instances of effect, iterate on them , print them (tostring() returns hashcode value) 10 different values.

if 2 instances of effect have same "damage" , "squaretype" must equal , have same hashcode.

update 3

the effects created this:

@override public void friendlyfire(basebullet bullet, basesquare square) {     square.notifyfriendlyfire(new effect(timeutils.millis(),             square.getdamage(), square.getsquaretype()), new mykey(square.getuniqueid())); } 

the effect's field changes timestamp, , don't use in equals , hashcode.

public void notifyfriendlyfire(effect neweffect, mykey key) {     // system.out.println("the map contains key? " + effectmap.containskey(key));     if(effectmap.containskey(key)) {         effect oldeffect = effectmap.get(key);         system.out.println(neweffect);         if(!oldeffect.equals(neweffect)) {             system.out.println("old effect changed!");             // remove old effect             removeeffect(oldeffect);             // update map new effect             effectmap.put(key, neweffect); //              // apply new effect             applyeffect(neweffect);         }     }     else {         // new effect         effectmap.put(key, neweffect);         applyeffect(neweffect);     } } 

the check "if(!oldeffect.equals(neweffect))" true, if damage , type same.

update 4

i've found bug. damage increases continuously. i've figure out why...

here's attempt @ approximating implementation:

package cruft;  import java.util.date;  /**  * equals , hashcode test  * creation date 1/16/2016.  * @link https://stackoverflow.com/questions/34826585/hashcode-changes-each-time-the-object-is-created  */ public class overridedemo {      private long timestamp;     private int damage;     private squaretype squaretype;       public overridedemo(int damage, squaretype squaretype) {         this(damage, squaretype, new date().gettime());     }      public overridedemo(int damage, squaretype squaretype, long timestamp) {         if (squaretype == null) throw new illegalargumentexception("square type cannot null");         this.timestamp = timestamp;         this.damage = damage;         this.squaretype = squaretype;     }      public long gettimestamp() {         return timestamp;     }      public int getdamage() {         return damage;     }      public squaretype getsquaretype() {         return squaretype;     }      @override     public boolean equals(object o) {         if (this == o) { return true; }         if (o == null || getclass() != o.getclass()) { return false; }          overridedemo = (overridedemo) o;          if (damage != that.damage) { return false; }         return squaretype == that.squaretype;      }      @override     public int hashcode() {         int result = damage;         result = 31 * result + squaretype.hashcode();         return result;     }      @override     public string tostring() {         return "overridedemo{" +                 "timestamp=" + timestamp +                 ", damage=" + damage +                 ", squaretype=" + squaretype +                 '}';     } }  enum squaretype { fire, wind, water, earth } 

here's junit test shows how methods behave. tests pass; think implementation correct.

package cruft;  import org.junit.assert; import org.junit.test;  /**  * junit test demonstrates testing equals , hashcode contract  * created michael  * creation date 1/16/2016.  * @link https://stackoverflow.com/questions/34826585/hashcode-changes-each-time-the-object-is-created  */ public class overridedemotest {      @test     public void testequals_null() {         overridedemo x = new overridedemo(5, squaretype.earth);         assert.assertfalse(x.equals(null));     }      @test     public void testequals_reflexive() {         overridedemo x = new overridedemo(5, squaretype.earth);         assert.asserttrue(x.equals(x));     }      @test     public void testequals_symmetric() {         overridedemo x = new overridedemo(5, squaretype.earth);         overridedemo y = new overridedemo(5, squaretype.earth);         assert.asserttrue(x.equals(y));         assert.asserttrue(y.equals(x));         assert.asserttrue(x.hashcode() == y.hashcode());     }      @test     public void testequals_transitive() {         overridedemo x = new overridedemo(5, squaretype.earth);         overridedemo y = new overridedemo(5, squaretype.earth);         overridedemo z = new overridedemo(5, squaretype.earth);         assert.asserttrue(x.equals(y));         assert.asserttrue(y.equals(z));         assert.asserttrue(z.equals(x));         assert.asserttrue(x.hashcode() == y.hashcode());         assert.asserttrue(y.hashcode() == z.hashcode());         assert.asserttrue(z.hashcode() == x.hashcode());     }      @test     public void testequals_differentdamage_notequal() {         overridedemo x = new overridedemo(5, squaretype.earth);         overridedemo y = new overridedemo(10, squaretype.earth);         assert.assertfalse(x.equals(y));         assert.assertfalse(y.equals(x));         assert.assertfalse(x.hashcode() == y.hashcode());     }      @test     public void testequals_differentsquaretype_notequal() {         overridedemo x = new overridedemo(10, squaretype.earth);         overridedemo y = new overridedemo(10, squaretype.fire);         assert.assertfalse(x.equals(y));         assert.assertfalse(y.equals(x));         assert.assertfalse(x.hashcode() == y.hashcode());     } } 

Comments

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

Cross-Compiling Linux Kernel for Raspberry Pi - ${CCPREFIX}gcc -v does not work -

java.lang.NoClassDefFoundError When Creating New Android Project -