"YOU AND THE ART OF ONLINE DATING" is the only product on the market that will take you step-by-step through the process of online dating, provide you with the resources to help ensure success. Get it now!
I don't think a nontrivial hashcode exists. Also, your equals() violates the general contract as stated in the API it is not transitive.
I don't think a nontrivial hashcode exists. Also, your equals() violates the general contract as stated in the API --- it is not transitive: (1,2) equals (1,3) (4,3) equals (1,3) But (4,3) is not equal to (1,2). For the sake of completeness, I present to you the Skeet-Niko proof =) Claim: The hashcode must be the trivial constant function.
Proof: Let (a,b) and (c,d) be two objects with distinct hashcodes, i.e. H(a,b) ≠h(c,d). Consider the object (a,d).
By the OP's definition, (a,d) is equal to (a,b), and (a,d) is equal to (c,d). It follows from the hashcode contract that h(a,d) = h(a,b) = h(c,d); a contradiction.
Darn your speedier edit than my frantic typing :) – Jon Skeet Jan 26 '09 at 8:40 You don't really need the contradiction. You could shorten it to: given two objects (a,b), (c,d). We find that h(a,b) = h(a,d) = h(c,d).
– nes1983 Jan 26 '09 at 9:29 Thanks, this made me think harder about my own GetHashCode() routines. – Ed S. Jan 26 '09 at 18:00.
Ok, in your scenario, ignoring the API requirements for a second, there is no non-constant hash function Imagine there were a hashfunction which has different values for (a,b), (a,c), b! =c, then hash(a,b)! = hash(a,c), eventhough (a,b) = (a,c).
Similarly, (b,a) and (c,a) must emit the same hashCode. Let's call our hash-function h. We find: h(x,y) = h(x,w) = h(v,w) forall x,y,v,w.
Hence, the only hashFunction that does what you want is constant.
1 +1 for the proof, which I have shamelessly used as the basis for mine. – Zach Scrivena Jan 26 '09 at 9:22.
I'm pretty sure Zach's right - there's no non-trivial hashcode to do this. Pseudo-proof: Consider any two non-equal values, X=(id1, name1) and Y=(id2, name2). Now consider Z=(id2,name1).
This is equal to both X and Y, so must have the same hashcode as both X and Y. Therefore X and Y must have the same hashcode - which means all values must have the same hashcode. There's a reason why you've got into a weird situation - you're breaking the transitive nature of equals.
The fact that X. Equals(Z) and Z. Equals(Y) should mean that X.
Equals(Y) - but it doesn't. Your definition of equality isn't suitable for the normal contract of equals.
Thank you for the endorsement! =) – Zach Scrivena Jan 26 '09 at 8:41 2 umm, this is, like, exactly what zach said, only more bloated. – nes1983 Jan 26 '09 at 8:46 "Bloated" in this case means more informative, in my humble opinion atleast.
Zach has the link going for him though. – Matthew Scharley Jan 26 '09 at 8:57 Niko: I was writing this while Zach was editing his. When I started writing it, Zach's answer was just "I don't think a nontrivial hashcode exists."
And yet you've written another answer with the same information in... – Jon Skeet Jan 26 '09 at 8:57 jon: alright, I didn't know he changed his post. – nes1983 Jan 26 '09 at 9:01.
I think you can't. The reason is, your equals() method is not transitive. Transitivity means for three non-null x, y, z, if x.
Equals(y), y. Equals(z), then x. Equals(z).
In your example, an object x={id: 1, name: "ha"}, y={id: 1, name: "foo"}, z={id: 2, name: "bar"} have this property (x. Equals(y) and y. Equals(z)).
However, x. Equals(z) is false. Every equals() method should have this property, see the Java API docs.
Back to hashing functions: Every function yields an equivalence defined by f(x)==f(y). That means if you are interested in comparison of the function values and want it to return true if x==y (and possibly in other cases), you'll receive a transitive relation, which means you have to consider at least a transitive closure of objects' equivalence. In your case, the transitive closure is the trivial relation (everything equals to anything).
Which means you can't distinguish different objects by any function.
If you meant "AND" then your hashcode should be calculated using the very same or less (but never use fields not used by equals) fields you are by equals(). If you meant "OR" then you r hashgcode should not include id or name in its hashcode calculation which doesn't really make sense.
EDIT: I didn't read the question carefully. -- I'll use commons-lang jar. XOR the members hashCode should works.As they should implements hashCode() and equals() correctly.
However, your code may wrong if you don't protect your hashCode. Once it was hashed, it should not be changed.It should be prevented from being happen. Public hashCode(){ return new AssertionError(); } or public class MyClass { final int id; final String name; // constructor } or public class MyClass { private int id; private String name; boolean hashed=false; public void setId(int value){ if(hashed)throw new IllegalStateException(); this.
Id=value; } public void setName(String value){ if(hashed)throw new IllegalStateException(); this.Name=value; } // your equals() here public hashCode(){ hashed=true; return new HashCodeBuilder(). Append(id). Append(name).toHashCode(); } }.
Hehe, this is smart. I like it. But still wrong.
Check out my proof. It does not rely on anything being changed after first setup. Every non-constant hash-function will go wrong.
And of course, immutability does not heal the non-transitivity. – nes1983 Jan 26 '09 at 9:19.
After re-read the question. You may auto-complete the another field when one of them being updated. -- EDIT: My code may say better then my English.
Void setName(String value){ this. Id=Lookup. IDbyName(value); } void setID(String value){ this.Name=Lookup.
NamebyId(value); } EDIT 2: The code on the question may wrong as will always return true unless you've set both the id & name. If you really want a method that do partial equals, create you own API that named "partialEquals()".
Super duh moment. Was trying to write hashCode() before validating equals() contract. Thanks to Zach Scrivena for the answer!
Thanks to every one else for their time and response.
What if we use TreeMap to replace HashMap. Is it possible to write a valid compareTo() method for MyClass?
The simplest route is to XOR the hashcodes of each individual field. This has minor ugliness in some situations (e.g. In X,Y coordinates, it causes the potentially poor situation of having equal hashes when you flip X and Y), but is overall pretty effective. Tweak as needed to reduce collisions if necessary for efficiency.
This doesn't fit the question - which I'd misread as well. If either of the fields changes, the hashcode will change. – Jon Skeet Jan 26 '09 at 8:34 With you guys solution, didn't you change his equal from (other.Id == this.
Id || other. Name == this.Name) to (other. Id == this.
Id && other.Name == this. Name)? – Tom Jan 26 '09 at 8:50.
How about this public override int GetHashCode() { return (id.ToString() + name.ToString()).GetHashCode(); } The function should allways return a "valid" hash... Edit: just noticed that you use "or" not "and" :P well I doubt there is any good solution to this problem...
Nope - that will produce different hashes for values which vary in one field but not the other. – Jon Skeet Jan 26 '09 at 8:40.
How about public override int GetHashCode() { return id.GetHashCode() ^ name.GetHashCode(); }.
This doesn't answer the question correctly - the hash code needs to be the same when only one of the fields is the same. Your answer requires both fields to provide the same hash for equality. – cjk Jan 26 '09 at 8:29 Geez, you're right, didn't give it enough thought.
– Ed S. Jan 26 '09 at 8:30 I hadn't read the question properly either... – Jon Skeet Jan 26 '09 at 8:35 Downvote removed after edit – cjk Jan 26 '09 at 8:39.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.