0

I want to declare a List<int[]> or Map<int[],Boolean> but it's very difficult because arrays in Java doesn't implement the equals() method. If two arrays a and b are equal, a.equals(b) returns false.

Although java.util.Arrays.equals() compares arrays for equality, how do I get a List to use that method for comparison instead of the screwed-up equals()?

By the way, the int[] is a array [x,y,z] describing a coordinate. I want to put a bunch of these coordinates into a List or Map.

0

4 Answers 4

9

Why not declare your own class for a point? e.g.

class Point3D {
  int x, y, z;

  public boolean equals() {
    // logic
  }
}

and then declare List<Point3D>.

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

2 Comments

Only make you fields private and the class immutable!
Valid comments, I omitted the details for clarity.
3

A general solution is to wrap the array in a method that does implement equals (and hashCode and perhaps compare, possibly toString and other methods that might make sense) as you wish:

public final class IntArrayWrapper {
    private final IntArrayWrapper[] values;
    public IntArrayWrapper(int... values) {
        if (values == null) {
            throw new NullPointerException();
        }
        this.values = values;
    }
    @Override public boolean equals(Object obj) {
        if (!(obj instanceof IntArrayWrapper)) {
            return false;
        }
        IntArrayWrapper other = (IntArrayWrapper)obj;
        return java.util.Arrays.equals(this.values, other.values);
    }
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(values);
    }
    public int[] getValues() {
        return values;
    }
    [...]
}

In this specific case, using arrays to contain certain fixed data values is poor design. Do it properly:

public final class Point {
    private final int x;
    private final int y;
    private final int z;

    public static Point of(int x, int y, int z) {
        return new Point(x, y, z);
    }
    private Point(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    @Override public boolean equals(Object obj) {
        if (!(obj instanceof Point)) {
            return false;
        }
        Point other = (Point)obj;
        return
            this.x == other.x &&
            this.y == other.y &&
            this.z == other.z;
    }
    @Override public int hashCode() {
        int hash;
        hash = x;
        hash = hash*41+y;
        hash = hash*41+z;
        return hash;
    }
    [...]
}

1 Comment

Java SE has Point2D, but no Point3d.
2

First of all, this isn't legal syntax. List can only take a single generic type.

Second, I would say that if you're worried about doing things at this low a level you aren't thinking abstractly enough. An array of arrays or a List of Lists is common enough. People who create matrix classes for linear algebra use them all the time. But you leverage objects and Java best when you hide those implementation details from clients of your class. Try it for your case and see if it helps.

Comments

0

You could always use the existing Point3d class instead of an array.

edit: The Apache Commons Math library also has some good options.

2 Comments

You are suggesting pulling in a huge dependent, dormant library for a single, trivial class? A class that uses the wrong datatype for the questioner and is mutable.
Yes. Though the Apache Commons library is also a good option.

Your Answer

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