Java hashCode for a Point class - java

I have a simple custom Point class as follows and I would like to know if my hashCode implemention could be improved or if this is the best it's going to get.
public class Point
{
private final int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
#Override
public boolean equals(Object other)
{
if (this == other)
return true;
if (!(other instanceof Point))
return false;
Point otherPoint = (Point) other;
return otherPoint.x == x && otherPoint.y == y;
}
#Override
public int hashCode()
{
return (Integer.toString(x) + "," + Integer.toString(y)).hashCode();
}
}

Please do not use Strings. There's a lot of theory behind this and several implementations (division method, multiplication one, etc...). If you have about a hour you can watch this MIT-Class
This being said, here is what Netbeans 7.1 suggests:
#Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + this.x;
hash = 71 * hash + this.y;
return hash;
}
October 2015 Edit
I started using IntelliJ a while back, I live happier now. This is what its automatic hashCode generation produces. It's a little less verbose. Note the use of prime numbers as well.
#Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}

The manual multiplication of values of all significant member fields as suggested by Gevorg is probably the most efficient and has a good value distribution. However, if you favour readability, there are nice alternatives available either in Java 7...
import java.util.Objects;
...
#Override
public int hashCode() {
return Objects.hash(x, y);
}
... or in the Guava library:
import com.google.common.base.Objects;
....
#Override
public int hashCode() {
return Objects.hashCode(x, y);
}
Both of these varags methods simply delegate to Arrays.hashCode(Object[] a), so there is a slight impact on performance because of the autoboxing of ints and creating an array of object references, but it should be far less significant than using reflection.
And the readability is just great, since you simply see, which fields are used for the hashcode computation and all the multiply and add syntax is just hidden under the hood of Arrays.hashCode(Object[] a):
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}

I would recommend using a simpler and more performant method without strings, perhaps Josh Bloch's method from this answer, in your case just:
return 37 * x + y;
EDIT: nybbler is correct. What is actually recommended is:
int result = 373; // Constant can vary, but should be prime
result = 37 * result + x;
result = 37 * result + y;

A really nice way to hash a 2D point into a single integer is to use a number spiral!
http://ulamspiral.com/images/IntegerSpiral.gif
#Override
public int hashCode() {
int ax = Math.abs(x);
int ay = Math.abs(y);
if (ax>ay && x>0) return 4*x*x-3*x+y+1;
if (ax>ay && x<=0) return 4*x*x-x-y+1;
if (ax<=ay && y>0) return 4*y*y-y-x+1;
return 4*y*y-3*y+x+1;
}
While this method requires a few more calculations, there will be no unpredictable collisions. It also has the nice property that points closer to the origin in general will have smaller hash value. (Still can overflow with x or y > sqrt(MAX_VALUE) however)

From the JDK's Point class (inherited from Point2d):
public int hashCode() {
long bits = java.lang.Double.doubleToLongBits(getX());
bits ^= java.lang.Double.doubleToLongBits(getY()) * 31;
return (((int) bits) ^ ((int) (bits >> 32)));
}
That looks slightly better than your implementation.

You can have a look into existing Point type classes implementations:
/**
343 * Returns the hashcode for this <code>Point2D</code>.
344 * #return a hash code for this <code>Point2D</code>.
345 */
346 public int hashCode() {
347 long bits = java.lang.Double.doubleToLongBits(getX());
348 bits ^= java.lang.Double.doubleToLongBits(getY()) * 31;
349 return (((int) bits) ^ ((int) (bits >> 32)));
350 }
from: http://kickjava.com/src/java/awt/geom/Point2D.java.htm#ixzz1lMCZCCZw
Simple guide for hashCode implementation can be found here

I used to write my own hash and equals functions then I found this : )
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
#Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
#Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
of course keep in mind the following:
Because reflection involves types that are dynamically resolved,
certain Java virtual machine optimizations can not be performed.
Consequently, reflective operations have slower performance than their
non-reflective counterparts, and should be avoided in sections of code
which are called frequently in performance-sensitive applications. SRC

By default, Eclipse will use a hashCode() function for your Point class similar to:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + x;
result = prime * result + y;
return result;
}
At the very least, incorporating a prime number into your hashCode algorithm will help with it's "uniqueness".

Related

What is the idea behind skipping chars in the old impl of String hashCode() in Java

What is the idea of skipping some characters from a String in old versions of Java's String hashCode() implementation:
public int hashCode() {
int hash = 0;
int skip = Math.max(1, length()/8);
for (int i = 0; i < length(); i += skip)
hash = (hash * 37) + charAt(i);
return hash;
}
In the current version there is no skipping and the prime number is 31 instead of 37
Probably to fast up the hashCode() computation but as consequence it had more potential collisions.
The new version favors less collisions but requires more computations.
But in the facts, Strings are immutable, so in more recent versions of hashCode(), that is computed once :
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
So in a some way it makes sense to favor this way as it reduces the collision number and not skipping some characters in the hashCode() computation is not so expensive as the result is cached.

Hash Codes for Floats in Java

I have a class with two float variables and hashCode method (without equals in current code snippet):
public class TestPoint2D {
private float x;
private float z;
public TestPoint2D(float x, float z) {
this.x = x;
this.z = z;
}
#Override
public int hashCode() {
int result = (x != +0.0f ? Float.floatToIntBits(x) : 0);
result = 31 * result + (z != +0.0f ? Float.floatToIntBits(z) : 0);
return result;
}
}
The following test
#Test
public void tempTest() {
TestPoint2D p1 = new TestPoint2D(3, -1);
TestPoint2D p2 = new TestPoint2D(-3, 1);
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
}
returns same values:
-2025848832
In this case I can't use my TestPoint2D within HashSet / HashMap
Can anyone suggest how to implement hashCode in this case or workarounds related to this?
P.S.
Added one more test:
#Test
public void hashCodeTest() {
for (float a = 5; a < 100000; a += 1.5f) {
float b = a + 1000 / a; // negative value depends on a
TestPoint3D p1 = new TestPoint3D(a, -b);
TestPoint3D p2 = new TestPoint3D(-a, b);
Assert.assertEquals(p1.hashCode(), p2.hashCode());
}
}
And it is passed that proves that
TestPoint2D(a, -b).hashCode() == TestPoint2D(-a, b).hashCode()
I would use Objects.hash():
public int hashCode() {
return Objects.hash(x, z);
}
From the Javadoc:
public static int hash(Object... values)
Generates a hash code for a sequence of input values. The hash code is generated as if all the input values were placed into an array, and that array were hashed by calling Arrays.hashCode(Object[]).
This method is useful for implementing Object.hashCode() on objects containing multiple fields. For example, if an object that has three fields, x, y, and z, one could write:
These auto-generated hashcode functions are not very good.
The problem is that small integers cause very "sparse" and similar bitcodes.
To understand the problem, look at the actual computation.
System.out.format("%x\n", Float.floatToIntBits(1));
System.out.format("%x\n", Float.floatToIntBits(-1));
System.out.format("%x\n", Float.floatToIntBits(3));
System.out.format("%x\n", Float.floatToIntBits(-3));
gives:
3f800000
bf800000
40400000
c0400000
As you can see, the - is the most significant bit in IEEE floats. Multiplication with 31 changes them not substantially:
b0800000
30800000
c7c00000
47c00000
The problem are all the 0s at the end. They get preserved by integer multiplication with any prime (because they are base-2 0s, not base-10!).
So IMHO, the best strategy is to employ bit shifts, e.g.:
final int h1 = Float.floatToIntBits(x);
final int h2 = Float.floatToIntBits(z);
return h1 ^ ((h2 >>> 16) | (h2 << 16));
But you may want to look at Which hashing algorithm is best for uniqueness and speed? and test for your particular case of integers-as-float.
according to the java specification, 2 objects can have the same hashCode and this doesnt mean they are equal...
the probability is small but exist...
on the other hand is always a good practice to override both equals and hashcode...
As I understand the problem, you expect a lot of symmetrical pairs of points among your keys, so you need a hashCode method that does not tend to give them the same code.
I did some tests, and deliberately giving extra significance to the sign of x tends to map symmetrical points away from each other. See this test program:
public class Test {
private float x;
private float y;
public static void main(String[] args) {
int collisions = 0;
for (int ix = 0; ix < 100; ix++) {
for (int iz = 0; iz < 100; iz++) {
Test t1 = new Test(ix, -iz);
Test t2 = new Test(-ix, iz);
if (t1.hashCode() == t2.hashCode()) {
collisions++;
}
}
}
System.out.println(collisions);
}
public Test(float x, float y) {
super();
this.x = x;
this.y = y;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (x >= 0) ? 1 : -1;
result = prime * result + Float.floatToIntBits(x);
result = prime * result + Float.floatToIntBits(y);
return result;
}
// Equals omitted for compactness
}
Without the result = (x >= 0) ? 1 : -1; line it is the hashCode() generated by Eclipse, and counts 9802 symmetrical point collisions. With that line, it counts one symmetrical point collision.

Correct implementation of the equals()-Method for fractions

I want that the printn methods give me "Asterix" and "Oberlix" since 3/4 is the same as 6/8.
HashMap hm = new HashMap();
hm.put(new Fraction(3, 4), "Asterix");
hm.put(new Fraction(19, 12), "Oberlix");
System.out.println(hm.get(new Fraction(6, 8)));
System.out.println(hm.get(new Fraction(38, 24)));
So that is how I implemented the equals-Method:
public boolean equals(Object obj) {
boolean isEqual = false;
if(obj instanceof Fraction) {
Fraction frac = (Fraction) obj;
if(((double) this.numerator / (double) this.denumerator) == ((double) frac.numerator / (double) frac.denumerator)) {
isEqual = true;
}
}
return isEqual;
}
Obviously I did something wrong, because that doesn't work and my print method returns "null". My idea was that if I devide the numerator and the denumerator of both fractions, the result must be equal, if the fractions are equal (3/4 is the same as 6/8).
Sorry guys, I guess the mistake must be somehow obvious but I can't find it.
You could do for equals
return denominator * other.numerator == numerator * other.denominator;
But nicer is to make canonical Fraction.
Either in the equals or in the constructor normalize the fraction: 6/8 becoming 3/4.
public class Fraction implements Number {
private final int numerator;
private final int denominator;
public Fraction(int numerator, int denominator) {
if (denominator < 0) {
denominator = -denominator;
numberator = -numerator;
}
int commonFactor = gcd(numerator, denominator);
this.numerator = numerator / commonFactor;
this.denominator = denominator / commonFactor;
}
#Override
public boolean equals(Object other) {
...
Fraction otherFraction = ...
return denominator == otherFraction.denominator
&& numerator == otherFraction.numerator;
}
private static int gcd(int x, int y) {
x = Math.abs(x);
y = Math.abs(y);
...
while (x != y) {
if (x > y) {
x -= y;
} else {
y -= x;
}
}
return x;
}
What is nicer? You can now make a hashCode:
#Override
int hashCode() {
return denominator * 31 + numerator;
}
Floating point is an approximating sum of a limited number of powers of 2.
For a HashMap to work, you need to implement both equals and hashCode. I'll provide a partial answer, for equals only, because I don't have much time.
To compare two fractions without resorting to doubles, just do some simple arithmetic. You have two fractions, a/b and c/d. Assuming the denominators are nonzero:
a/b == c/d
(multiply left and right by b)
a == c/d*b
(multiply left and right by d)
a*d == c*b
So:
public boolean equals(Object obj) {
if (!(obj instanceof Fraction)) {
return false;
}
Fraction other = (Fraction) obj;
return this.numerator * other.denominator == other.numerator * this.denominator;
}
Note that this won't work for very large fractions; they will overflow. Cast to long if you want to deal with these correctly.
For implementing hashCode, you could simplify the fraction using the Euclidean algorithm, then xor the hash codes of the numerator and the denominator.
You should never compare double with == because System.out.println(0.1+0.1+0.1) will not always be 0.3 (for me, it output 0.30000000000000004). Use equals or compare method from Double.
Because you are storing both numerator and denumenator in your class Fraction, you should use a close enough condition with a custom epsilon in your equals method:
public boolean equals(Object obj) {
boolean isEqual = false;
if(obj instanceof Fraction) {
Fraction frac = (Fraction) obj;
if(Math.abs(((double)this.numerator)/this.denumerator) - ((double)frac.numerator)/frac.denumerator) < .00000001/*epsilon*/) {
isEqual = true;
}
}
return isEqual;
}
Also, you will need to override the hashCode method in your class Fraction in order to use HashMap. Since this equals implementation only depend on one value (the result of the fraction) you could use the following :
public int hashCode()
{
return 0;//all Fraction return the same hashCode, which make HashMap call equals each time
//EDIT: the following is WRONG: assuming eps = 0.1, 299/100 is equals to 300/100 but hashCode will be different (2 and 3).
//return this.numerator/this.denumerator ;//since those are int (I guess),
//it will truncate the floating part. So you will just check for the integer part.
}
as the posts from above, the way to your solution is the use of "hasCode()" and not equals().
Here is an option on how you can get the proper hashCode:
#Override
public int hashCode() {
// Calculating with double is troublesome sometimes, so i use BigDecimal here
BigDecimal value = BigDecimal.valueOf(this.numerator).divide(BigDecimal.valueOf(this.denumerator), RoundingMode.HALF_UP);
// after this, i just return the hashCode i would get, if if my parameter was a simple Double Value:
return Double.valueOf(value.doubleValue()).hashCode();
}
hope this helps!

Resizing Arrays for Speed

So, I am writing a Befunge Interpreter in Java. I have almost all of it down, except I can't figure out a good solution to the problem of Funge Space. Currently I'm using the style stated in the Befunge 93 specs, which is a 80x25 array to hold the code.
In Funge, though, I'm supposed to have an "infinite" array of code (or 4,294,967,296 x 4,294,967,296, which is -2,147,483,648 to 2,147,483,648 in both dimensions), but obviously it's never a good idea to have that much space allocated. But as well as this, it doesn't seem like a good idea to create a new array and copy every character into it every time the program steps out of bounds. Is there a solution to this problem that I'm missing?
So basically, my problem is that I need to somehow expand the array every time I reach out of bounds, or use some sort of other data structure. Any suggestions?
Funge 98 specs
Also, by the way, I still have never figure out how to pronounce Befunge or Funge, I always just say it like "Bee-funj" and "funj"
Without having read the specs (no - I mean, just NO!): A 4,294,967,296 x 4,294,967,296 array is obviously a highly theoretical construct, and only a tiny fraction of these "array entries" can and will ever be used.
Apart from that: Regardless of whether you use an array or any other collection, you'll have a problem with indexing: Array indices can only be int values, but 4,294,967,296 is twice as large as Integer.MAX_VALUE (there are no unsigned ints in Java).
However, one way of representing such an "infinitely large" sparse 2D array would be a map that maps pairs of long values (the x and y coordinates) to the array entries. Roughly like this:
import java.util.HashMap;
import java.util.Map;
interface Space<T>
{
void set(long x, long y, T value);
T get(long x, long y);
}
class DefaultSpace<T> implements Space<T>
{
private final Map<LongPair, T> map = new HashMap<LongPair, T>();
#Override
public void set(long x, long y, T value)
{
LongPair key = new LongPair(x,y);
if (value == null)
{
map.remove(key);
}
else
{
map.put(key, value);
}
}
#Override
public T get(long x, long y)
{
return map.get(new LongPair(x,y));
}
}
class LongPair
{
private final long x;
private final long y;
LongPair(long x, long y)
{
this.x = x;
this.y = y;
}
#Override
public String toString()
{
return "("+x+","+y+")";
}
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + (int) (x ^ (x >>> 32));
result = prime * result + (int) (y ^ (y >>> 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;
LongPair other = (LongPair) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}

How to write a function that can calculate power in Java. No loops

I've been trying to write a simple function in Java that can calculate a number to the nth power without using loops.
I then found the Math.pow(a, b) class... or method still can't distinguish the two am not so good with theory. So i wrote this..
public static void main(String[] args) {
int a = 2;
int b = 31;
System.out.println(Math.pow(a, b));
}
Then i wanted to make my own Math.pow without using loops i wanted it to look more simple than loops, like using some type of Repeat I made a lot of research till i came across the commons-lang3 package i tried using StringUtils.repeat
So far I think this is the Syntax:-
public static String repeat(String str, int repeat)
StringUtils.repeat("ab", 2);
The problem i've been facing the past 24hrs or more is that StringUtils.repeat(String str, int 2); repeats strings not out puts or numbers or calculations.
Is there anything i can do to overcome this or is there any other better approach to creating a function that calculates powers?
without using loops or Math.pow
This might be funny but it took me while to figure out that StringUtils.repeat only repeats strings this is how i tried to overcome it. incase it helps
public static int repeat(int cal, int repeat){
cal = 2+2;
int result = StringUtils.repeat(cal,2);
return result;
}
can i not use recursion maybe some thing like this
public static RepeatThis(String a)
{
System.out.println(a);
RepeatThis(a);
}
just trying to understand java in dept thanks for all your comments even if there were syntax errors as long as the logic was understood that was good for me :)
Another implementation with O(Log(n)) complexity
public static long pow(long base, long exp){
if(exp ==0){
return 1;
}
if(exp ==1){
return base;
}
if(exp % 2 == 0){
long half = pow(base, exp/2);
return half * half;
}else{
long half = pow(base, (exp -1)/2);
return base * half * half;
}
}
Try with recursion:
int pow(int base, int power){
if(power == 0) return 1;
return base * pow(base, --power);
}
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
This one handles negative exponential:
public static double pow(double base, int e) {
int inc;
if(e <= 0) {
base = 1.0 / base;
inc = 1;
}
else {
inc = -1;
}
return doPow(base, e, inc);
}
private static double doPow(double base, int e, int inc) {
if(e == 0) {
return 1;
}
return base * doPow(base, e + inc, inc);
}
I think in Production recursion just does not provide high end performance.
double power(double num, int exponent)
{
double value=1;
int Originalexpn=exponent;
double OriginalNumber=num;
if(exponent==0)
return value;
if(exponent<0)
{
num=1/num;
exponent=abs(exponent);
}
while(exponent>0)
{
value*=num;
--exponent;
}
cout << OriginalNumber << " Raised to " << Originalexpn << " is " << value << endl;
return value;
}
Use this code.
public int mypow(int a, int e){
if(e == 1) return a;
return a * mypow(a,e-1);
}
Sure, create your own recursive function:
public static int repeat(int base, int exp) {
if (exp == 1) {
return base;
}
return base * repeat(base, exp - 1);
}
Math.pow(a, b)
Math is the class, pow is the method, a and b are the parameters.
Here is a O(log(n)) code that calculates the power of a number. Algorithmic technique used is divide and conquer. It also accepts negative powers i.e., x^(-y)
import java.util.Scanner;
public class PowerOfANumber{
public static void main(String args[]){
float result=0, base;
int power;
PowerOfANumber calcPower = new PowerOfANumber();
/* Get the user input for the base and power */
Scanner input = new Scanner(System.in);
System.out.println("Enter the base");
base=input.nextFloat();
System.out.println("Enter the power");
power=input.nextInt();
result = calcPower.calculatePower(base,power);
System.out.println(base + "^" + power + " is " +result);
}
private float calculatePower(float x, int y){
float temporary;
/* Termination condition for recursion */
if(y==0)
return 1;
temporary=calculatePower(x,y/2);
/* Check if the power is even */
if(y%2==0)
return (temporary * temporary);
else{
if(y>0)
return (x * temporary * temporary);
else
return (temporary*temporary)/x;
}
}
}
Remembering the definition of the logarithm, this can be done with ln and exp if these functions are allowed. Works for any positive base and any real exponent (not necessarily integer):
x = 6.7^4.4
ln(x) = 4.4 * ln(6.7) = about 8.36
x = exp(8.36) = about 4312.5
You can read more here and also here. Java provides both ln and exp.
A recursive method would be the easiest for this :
int power(int base, int exp) {
if (exp != 1) {
return (base * power(base, exp - 1));
} else {
return base;
}
}
where base is the number and exp is the exponenet

Categories

Resources