1

I have some code as such:

@Override
public int hashCode() {
    int hash = 5;
    hash = 47 * hash + Objects.hashCode(this.bendWidth);
    hash = 47 * hash + Objects.hashCode(this.bendSideLength);
    hash = 47 * hash + Objects.hashCode(this.thickness);
    hash = 47 * hash + Objects.hashCode(this.innerRadius);
    hash = 47 * hash + Objects.hashCode(this.bendAngle);
    hash = 47 * hash + Objects.hashCode(this.kfactor);
    hash = 47 * hash + Objects.hashCode(this.bendShortening);
    return hash;
}

and I'm looking to make this source work for 1.6

So far I've tried guava:

@Override
public int hashCode() {
    int hash = 5;


    Object[] objs = new Object[]{
        this.getPointND().getPoint()[0],
        this.getPointND().getPoint()[1],
        this.getPointND().getPoint()[2],
        this.getPointND().getPoint()[3],
        this.getPointND().getPoint()[4],
        this.kfactor,
        this.bendShortening
    };

    hash = 47 * hash + Objects.hashCode(objs);

    hash = 47 * hash + Objects.hashCode(this.bendWidth);
    hash = 47 * hash + Objects.hashCode(this.bendSideLength);
    hash = 47 * hash + Objects.hashCode(this.thickness);
    hash = 47 * hash + Objects.hashCode(this.innerRadius);
    hash = 47 * hash + Objects.hashCode(this.bendAngle);
    hash = 47 * hash + Objects.hashCode(this.kfactor);
    hash = 47 * hash + Objects.hashCode(this.bendShortening);
    return hash;
}

And I've tried a solution as so:

   @Override
    public int hashCode() {
        int hash = 5;


        Object[] objs = new Object[]{
            this.getPointND().getPoint()[0],
            this.getPointND().getPoint()[1],
            this.getPointND().getPoint()[2],
            this.getPointND().getPoint()[3],
            this.getPointND().getPoint()[4],
            this.kfactor,
            this.bendShortening
        };

        hash = 47 * hash + Objects.hashCode(objs);

        hash = 47 * hash + Objects.hashCode(this.bendWidth);
        hash = 47 * hash + Objects.hashCode(this.bendSideLength);
        hash = 47 * hash + Objects.hashCode(this.thickness);
        hash = 47 * hash + Objects.hashCode(this.innerRadius);
        hash = 47 * hash + Objects.hashCode(this.bendAngle);
        hash = 47 * hash + Objects.hashCode(this.kfactor);
        hash = 47 * hash + Objects.hashCode(this.bendShortening);
        return hash;
    }

But still this test returns fails:

@Test
public void testHashCodeIsDifferentHashCode() {
    try {
        DataPoint pointOne = new DataPoint();
        pointOne.setBendAngle(new Double(1));
        pointOne.setBendShortening(new Double(1));
        pointOne.setBendSideLength(1);
        pointOne.setBendWidth(1);
        pointOne.setInnerRadius(1);
        pointOne.setKfactor(new Double(1));
        pointOne.setThickness(1);

        DataPoint pointTwo = new DataPoint();
        pointTwo.setBendAngle(0);
        pointTwo.setBendShortening(new Double(0));
        pointTwo.setBendSideLength(0);
        pointTwo.setBendWidth(0);
        pointTwo.setInnerRadius(0);
        pointTwo.setKfactor(new Double(0));
        pointTwo.setThickness(0);

        DataPoint pointThree = new DataPoint();
        pointThree.setBendAngle(Double.NaN);
        pointThree.setBendShortening(Double.NaN);
        pointThree.setBendSideLength(Double.NaN);
        pointThree.setBendWidth(Double.NaN);
        pointThree.setInnerRadius(Double.NaN);
        pointThree.setKfactor(Double.NaN);
        pointThree.setThickness(Double.NaN);

        Set<DataPoint> map = new HashSet<DataPoint>();
        map.add(pointOne);
        map.add(pointTwo);
        assert (map.size() == 2);
    } catch (NullPointerException ex) {
        assert false : "failed due to null";
    } catch (Exception ex) {
        assert false : "failed, unknown error.";
    }
}

Have tried this:

@Override
public int hashCode() {
    int hash = 5;
    hash = 47 * hash + Objects.hashCode(this.bendWidth);
    hash = 47 * hash + Objects.hashCode(this.bendSideLength);
    hash = 47 * hash + Objects.hashCode(this.thickness);
    hash = 47 * hash + Objects.hashCode(this.innerRadius);
    hash = 47 * hash + Objects.hashCode(this.bendAngle);
    hash = 47 * hash + Objects.hashCode(this.kfactor);
    hash = 47 * hash + Objects.hashCode(this.bendShortening);
    return hash;
}
public class Objects {

    public static int hashCode(Object object) {
        return object == null ? 0 : object.hashCode();
    }
}

My equals solution is as so:

@Override
public boolean equals(Object obj) {
    if (obj instanceof DataPoint) {
        DataPoint od = (DataPoint) obj;
        return (this.bendAngle == od.bendAngle)
                && (this.bendShortening == od.bendShortening)
                && (this.bendSideLength == od.bendSideLength)
                && (this.bendWidth == od.bendWidth)
                && (this.innerRadius == od.innerRadius)
                && (this.kfactor == od.kfactor)
                && (this.thickness == od.thickness);
    }
    return false;
}
4
  • 1
    Nope, this was added in jdk 1.7. You will have to roll your own solution. Commented May 30, 2013 at 17:32
  • In any case your IDE of choice should have some intelligent "Generate equals() and hashcode()" function. Commented May 30, 2013 at 17:35
  • 1
    Note that, even for primitive-boxing wrapper-types like Double, the == notation denotes reference-equality (identity), not structural equality (equality of value). For example, new Double(0.0) == new Double(0.0) evaluates to false, because they are references to two distinct instances of Double. You must keep this in mind when writing your equals method. Commented May 31, 2013 at 6:11
  • @ruakh That was exactly the problem amigo! Much appreciated! Commented May 31, 2013 at 15:09

3 Answers 3

4

There's nothing in JDK 1.6, but it's utterly trivial to write it yourself:

public static int hashCode(Object object) {
    return object == null ? 0 : object.hashCode();
}

Or - preferrably, IMO - start using Guava which has a familiar-looking Objects class. (It's not quite the same, as it only has the version taking an array via varargs, but that just means you can write your method in a single call.)

I suspect that you'll find that if you look closely at Guava, there are a bunch of useful things in there which you'll start using - I know I wouldn't want to write any signficant amount of Java code these days without Guava or something very similar.

If this were a dependency just for Objects.hashCode I'd just implement that method myself, but I'm sure there are other things you'll find useful.

Sign up to request clarification or add additional context in comments.

2 Comments

@dah: Well you need to override equals as well - have you done that? And hash maps will only prevent duplicate keys - it's not clear whether you're using this for keys or values.
Sorry. I meant hash sets. I've added the solutions I've tried, as well as my equals routine to the question.
2

This is one option:

@Override
public int hashCode() {
    return Arrays.asList(this.bendWidth, this.x, this.y).hashCode();
}

Is null safe, and generates a good hash code. There is also an Objects class in quava:

com.google.common.base.Objects

Comments

0

The equals method was the problem. a new Double(0.0) == new Double(0.0) evaluates to false.

1 Comment

Another "victory" for auto-unboxing wasting our time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.