I used eclipse to generate the overriding of the Object's hashCode and equals methods and that generated a few questions regarding the hashCode overriding. Is the below hashCode() correct?
Questions:
-Why does eclipse generate two result = lines of code? I would think that adding the two results together is appropriate. Any ideas why they're separate assignments?
-Can the final int prime be any prime number?
-Should int result always be 1?
public class Overrider {
private Long id;
private String name;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Overrider other = (Overrider) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Looks fine to me.
"Why does eclipse generate two result = lines of code?"
I'm guessing the reason is readability. It looks like you are multiplying the first result + the hash of the second field by the prime again, not just adding the two lines together. The generated code looks a lot better than:
result = (prime * result + ((id == null) ? 0 : id.hashCode())) +
(prime * (prime * result + ((id == null) ? 0 : id.hashCode())) +
((name == null) ? 0 : name.hashCode()));
"Can the final int prime be any prime number?"
Yep, but the higher the better. A higher number reduces the likelihood of a collision. In most cases 31 should be more than sufficient.
"Should int result always be 1?"
Assuming you mean "Should int result always be initialized to 1":
No, it just needs to be some constant that isn't 0.
-Why does eclipse generate two result = lines of code? I would think that adding the two results together is appropriate. Any ideas why they're separate assignments?
Answer : You have fix prime number defined above 'final int prime = 31;'.
Assume following cases
id.hashcode()=1 & name.hashcode()=2.
Hashcode by addition = 32+33=65 Hashcode with eclipse Implementation= 994
id.hashcode()=2 & name.hashcode()=1.
Hashcode by addition = 33+32=65 Hashcode with eclipse Implementation= 1024
Hashcode should be as unique as possible for better performance. With addition of results there is possibility of 2 different objects return same hashcode. Whereas with multiplication, there is very less chance to have duplicate hashcodes for different object.
-Can the final int prime be any prime number?
It can be any number but it ensures that there will be very less possible duplicate hashcodes for different objects. E.g 31 above represents that even if difference of 1 in id.hashcodes of 2 different objects will ensure that actual hashcodes of these 2 objects will differ by atleast 31. S
-Should int result always be 1?
It can be anything. It's just it should be non-zero and should avoid complexity in calculations to make it work fast.
-Why does eclipse generate two result = lines of code? I would think that adding the two results together is appropriate. Any ideas why
they're separate assignments?
Please remember that this is code that runs in eclipse to generate code. Therefore, there is a specific logic.
It is much easier to generate one line per variable instead of one line for all.
Also, it makes the code much more readable... can you imagine combining those two statements into one?
return prime * (prime + ((id == null) ? 0 : id.hashCode()) ) +
((name == null) ? 0 : name.hashCode());
I will not bother with simplifying that but it would become quite large and hideous if there were 10 class variables...
"Can the final int prime be any prime number?"
Have a look at: Why does Java's hashCode() in String use 31 as a multiplier?
I am quoting from there, which quotes the Book "Effective Java"...
According to Joshua Bloch's Effective Java (a book that can't be
recommended enough, and which I bought thanks to continual mentions on
stackoverflow):
"The value 31 was chosen because it is an odd prime. If it were even
and the multiplication overflowed, information would be lost, as
multiplication by 2 is equivalent to shifting. The advantage of using
a prime is less clear, but it is traditional. A nice property of 31 is
that the multiplication can be replaced by a shift and a subtraction
for better performance: 31 * i == (i << 5) - i. Modern VMs do this
sort of optimization automatically."
Related
I have a quick question on an assignment I'm trying to finish up. I'm writing a boolean method that takes three digit parameters (0-9) and returns true if they can be re arranged to make up a sequence. The hard part, for me at least, is that 0 can make a sequence with 8, 9, or 1,2. The three numbers are assumed to all be different. To be clear, the number 5,7,6 would be true because it can be rearranged to be 5, 6, 7, a sequence. Also 8,0,9 would return true, but 2,4,7 would not. I'm hoping someone can point me in the right direction with this, any help at all would be much appreciated!
You only need to check the validity of two tests:
Are all numbers different?
Is the absolute difference between the extremes 2?
This would give you the following method:
public static boolean isSequence(int a, int b, int c) {
if(a == 0) a = 10;
if(b == 0) b = 10;
if(c == 0) c = 10;
//Add the commented-out lines to make it safe to use with non-different numbers.
//boolean allDifferent = !(a == b) && !(b == c) && !(a == c);
boolean extremesIsTwo = Math.abs(Math.max(Math.max(a, b), c)
- Math.min(Math.min(a, b), c)) == 2;
//return allDifferent && extremesIsTwo;
return extremesIsTwo;
}
When you look at it, it's only a matter of simple logic, and finding the shortest path to the answer. There might be more optimized ways to do this, but this is clear, readable and works just fine.
Now, if you really want to get grinding on a problem of the like, you could either try to optimize this algorithm, or find another way to check that the three numbers are a sequence.
EDIT This version is scalable. And even though your requirements are for three arguments, I would still consider this solution, because it uses OOP to avoid repetition of code. As requested, it also doesn't check for duplicates.
public static boolean isSequenceScalable(List<Integer> list) {
list = list.stream().map(i -> i = (i == 0) ? 10 : i).collect(Collectors.toList());
list.sort(Integer::compareTo);
if (Math.abs(list.get(0) - list.get(list.size() - 1)) == 2) return true;
return false;
}
First of all I know this is kind of a simple question and I am a beginner so please bear with me .
I have been having problems with this exercise in Java and I'm practising for a test and this one really messed up my self-confidence.
So anyways the problem looks like this
// Returns true if (and only if) n is a prime number; n > 1 is assumed.
private static boolean isPrime(long n) {
return isPrime(n, 2);
// See the method isPrime below.
}
// Helper method for isPrime ...
private static boolean isPrime(long n, long m) {
return (m * n > (m /* TODO: modify expression if necessary */))
|| (n % m == (0 /* TODO: modify expression if necessary */)
&& isPrime((m /* TODO: modify expression if necessary */), n + 1));
}
So you're supposed to fill these expressions inside of the brackets where TODO is .
My problem is that I just can't trace what this does.
isPrime((.....),n+1);
If someone could just offer some advice on how to start solving this problem I would be very grateful .
This problem is not amenable to recursive solution. Or at least not an efficient recursive solution.
The definition of primality is that N is prime if it is not divisible by any positive integer other than itself or 1. The normal way to handle that using recursion would be to define a recursive "is_divisible" function:
# for integers m >= 1
is_prime(m):
return is_divisible(m, 1)
is_divisible(m, n):
if n >= m: return true
if n == 1: return is_divisible(m, n + 1)
if m % n == 0: return false // HERE
return is_divisible(m, n + 1)
OR (more efficient 3 parameter version)
# for all integers m
is_prime(m):
if m == 1: return false
if m >= 2: return is_divisible(m, sqrt(m), 2)
error "m is not a positive integer"
is_divisible(m, max, n) :
if n >= max: return true
if m % n == 0: return false // HERE
return is_divisible(m, max, n + 1)
(In the literature, they often call functions like is_divisible "auxiliary" functions. This is a common tool in functional programming.)
If you try to "optimize" that to only consider prime numbers at HERE, you will end up with double recursion .. and exponential complexity.
This is all very "unnatural" in Java, and will be horribly inefficient (even compared with a naive primality test using a loop1) because Java doesn't do tail-call optimization of recursion. Indeed, for large enough N you will get a StackOverflowError.
1 - A better, but still simple approach is the Sieve of Erathones. There are better tests for primality than that, though they are rather complicated, and in some cases probabilistic.
I have a POJO having ~450 fields and I'm trying to compare instances of this POJO using hascode. I've generated the overridden hashCode() method with eclipse. In quite a few cases the generated hashcode is crossing the integer boundary. As a result, it's getting difficult to perform the comparison. What's the workaround?
The hashCode() method is as follows:
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((stringOne == null) ? 0 : stringOne.hashCode());
result = prime * result + intOne;
result = prime * result + Arrays.hashCode(someArray);
result = prime * result + ((stringTwo == null) ? 0 : stringTwo.hashCode());
result = prime * result + intTwo;
result = prime * result + intThree;
result = prime * result + ((stringThree == null) ? 0 : stringThree.hashCode());
result = prime * result + ((stringFour == null) ? 0 : stringFour.hashCode());
result = prime * result + ((stringFive == null) ? 0 : stringFive.hashCode());
result = prime * result + ((objectOne == null) ? 0 : objectOne.hashCode());
result = prime * result + ((objectTwo == null) ? 0 : objectTwo.hashCode());
return result;
}
Integer overflow is a normal part of hashCode() calculations. It is not a problem.
For example, the hashCode() of a String is often negative.
System.out.println("The hashCode() of this String is negative".hashCode());
If a hashCode() calculation can overflow, obviously that can mean that unequal Objects can have the same hashCode, but this can happen without overflow. For example, both of these print true.
System.out.println("Aa".hashCode() == "BB".hashCode());
System.out.println(new HashSet<>(Arrays.asList(1, 2)).hashCode() == Collections.singleton(3).hashCode());
The only requirement is that equal objects should have the same hashCode. There is no requirement that different objects should have different hashCodes.
hashCode() and equals() should also be quick. You can improve the performance of equals() by comparing the fields most likely to be different first and returning early. You can't do this with hashCode() because the calculation must involve all the relevant fields. If your class has 450 fields, you may want to consider caching the result of hashCode() or, better, refactoring your class into smaller units.
The other thing to consider is whether you need to override these methods at all. It is only absolutely necessary if the objects are going to used as keys in a hash based container, such as HashMap.
The workaround is to use a different method to compute the hashcode. For instance, you could xor the hashcodes of your 450 fields (btw: wow!), but without knowing more about your object it's hard to say whether that would be a good approach for your particular case.
Ideally, since hashcodes are used for hashing, objects that are not equal should also with high probability produce different hashcodes.
I am writing a class Vec2D, representing a 2 dimensional vector. I store x and y in doubles.
When asked to generate equals(Object obj and hashCode(), eclipse generated this:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Vec2D other = (Vec2D) obj;
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
return false;
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
return false;
return true;
}
What is the significance of Double.doubleToLongBits(x) in this context? Can I not simply write x != other.x?
Short answer: Eclipse uses Double.doubleToLongBits because that's what Double.equals does:
The result is true if and only if the argument is not null and is a Double object that represents a double that has the same value as the double represented by this object. For this purpose, two double values are considered to be the same if and only if the method doubleToLongBits(double) returns the identical long value when applied to each.
Long answer: the JLS specifies a few differences between Double.equals and ==. For one difference specified in JLS 4.2.3 and JLS 15.21.1:
Positive zero and negative zero compare equal; thus the result of the expression 0.0==-0.0 is true and the result of 0.0>-0.0 is false. But other operations can distinguish positive and negative zero; for example, 1.0/0.0 has the value positive infinity, while the value of 1.0/-0.0 is negative infinity.
Another regards NaN:
If either operand is NaN, then the result of == is false but the result of != is true.
Indeed, the test x!=x is true if and only if the value of x is NaN.
As you can see, it's possible for two double values to compare with == but actually correspond to different behavior when used in math and hash tables. Thus, when writing a generated equality method, Eclipse makes the assumption that two doubles are only equal if and only if all operations that can be done to them are identical, or (equivalently) if they were autoboxed and compared with their equals methods. This is particularly important if switching between double and Doubleāit would be particularly unexpected for equality properties to differ there.
Of course, you're free to drift from that assumption: Regardless of whether it's a good idea, you may assign special cases to any of the many possible NaN representations, in which case Double.doubleToRawLongBits() would be a better match for your equals and hashCode methods. By the same token, your use case might treat objects with +0.0 and -0.0 as equivalent and guarantee that NaN values are not possible, in which case a raw == comparison may work better for equals (but at which point emulating the same criteria for hashCode becomes difficult).
Because == and != follow IEEE-754 semantics for doubles, Double.NaN != Double.NaN and 0.0 == -0.0. These behaviors may not be what you want, so Double.doubleToLongBits() converts the 64 bits of double data to 64 bits of long data so that operations like bit shifts and XOR work.
Honestly, though, I would say that the use of doubleToLongBits is a bug here, since if you care about exact equality you should be using Double.doubleToRawLongBits() (which does not perform any translations on the double data at all) instead.
A quick glance at the online javadoc yields this:
Returns a representation of the specified floating-point value according to the IEEE 754 floating-point "double format" bit layout.
...
In all cases, the result is a long integer that, when given to the longBitsToDouble(long) method, will produce a floating-point value the same as the argument to doubleToLongBits (except all NaN values are collapsed to a single "canonical" NaN value).
So it's probably a way of standardizing the double representations of x and y, as NaN can have multiple double representations
Assuming you were going to write a function / method to find a prime number, what would be the most efficient way to do this? I'm thinking that it would be a test that is something like this:
Code Below in semi-c++
bool primeTest (int x) { //X is the number we're testing
int testUpTo = (int)((sqrt(x))+1);
for (int i=3; i<testUpTo; i+=2){
if ((x%i)==0) {
return false;
}
}
return true;
}
Does someone have a better way to go about solving this that will take less computations?
edit: Changed code slightly, twice. I didn't write this with any specific language in mind, although I suppose it's C++ over java due to the word bool.
I would use the Miller Rabin test, which can easily be made deterministic for numbers smaller than 341,550,071,728,321 (and 2^31 is much smaller than that).
Pseudocode: there are a number of different cases.
x smaller than 9: Return (x & 1) != 0 || x == 2
x smaller than about 200 (tweakable): use trial division (what you used)
x smaller than 1373653: use Miller Rabin with bases 2 and 3.
x smaller than 4759123141 (that is everything else): use Miller Rabin with bases 2, 7 and 61.
Apart from 2 and 3, all prime numbers are one more or one less than a multiple of six. Using that fact would improve your code. Something like this (untested)
bool primeTest (int x){//X is the number we're testing
if (x == 1) return false;
if (x == 2 || x == 3) return true;
if(x%2 == 0 || x%3 == 0)
return false;
int testUpTo = (int)((sqrt(x))+1);
for(int i=6; i<testUpTo; i+=6){
if ((x%(i-1))==0 || x%(i+1)==0){
return false;
}
}
return true;
}
Of course there has been centuries of advanced mathematics to try and find more efficient primality tests.
Wikipedia has a pretty good article on that:
http://en.wikipedia.org/wiki/Primality_test
You can have a look at this paper who test the performance of different primality tests :
PRIMALITY TESTING by Richard P. Brent: http://cs.anu.edu.au/student/comp4600/lectures/comp4600_primality.pdf
(see this other post : What is the fastest deterministic primality test for numbers in the range 2^1024 to 2^4096?)
You can improve your code testing only odd values.
bool primeTest (int x){//X is the number we're testing
if(x == 2)
return true;
int testUpTo = (int)((sqrt(x))+1);
for(int i=3; i<testUpTo; i+=2){
if ((x%i)==0){
return false;
}
}
return true;
}