0

I have class Point with overridden methods equals() и hashCode():

public class Point {
    private double x;
    private double y;

    public Point() {
    }

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Point point = (Point) obj;
        if (this.x != point.getX()) {
            return false;
        }
        if (this.y != point.getY()) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        return (int) (31 * x + y);
    }
}

I create points:

        p1 = new Point(1.0, 1.0);
        p2 = new Point(1.0, 2.0);
        p3 = new Point(1.0, 4.0);
        p4 = new Point(5.0, 5.0);

This is arrays of Points - combinations:

        Point[] combinationPoints1 = {p1, p2, p3};
        Point[] combinationPoints2 = {p1, p2, p4};
        Point[] combinationPoints3 = {p1, p3, p4};
        Point[] combinationPoints4 = {p2, p3, p4};

Create List<Point[]>:

List<Point[]> expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List<Point[]> expectedResult2 = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

Compare 2 List<Point[]> and get message true:

List<Point[]> expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List<Point[]> expectedResult2 = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

expectedResult.equals(expectedResult2);    // TRUE

When I'm try change order to this:

List<Point[]> expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List<Point[]> expectedResult2 = Arrays.asList(combinationPoints2, combinationPoints1, combinationPoints3, combinationPoints4);

When comparing, I get false:

expectedResult.equals(expectedResult2);    // FALSE

Why?

UPDATE 29.08.2020
I have 2 List<Point[]>:

// FIRST
List<Point[]> expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

and

List<Point[]> actualResult = calculatePoint.getCombinationsElementsOver(startingPoints, pointsOnLine);

with contents:

for(Point[] p1 : expectedResult) {
            System.out.println(Arrays.toString(p1));
        }
// FIRST

[Point (1.0; 1.0), Point (1.0; 2.0), Point (1.0; 4.0)]
[Point (1.0; 1.0), Point (1.0; 2.0), Point (5.0; 5.0)]
[Point (1.0; 1.0), Point (1.0; 4.0), Point (5.0; 5.0)]
[Point (1.0; 2.0), Point (1.0; 4.0), Point (5.0; 5.0)]
for(Point[] p1 : actualResult) {
            System.out.println(Arrays.toString(p1));
        }

// SECOND
[Point (1.0; 1.0), Point (1.0; 2.0), Point (1.0; 4.0)]
[Point (1.0; 1.0), Point (1.0; 2.0), Point (5.0; 5.0)]
[Point (1.0; 1.0), Point (1.0; 4.0), Point (5.0; 5.0)]
[Point (1.0; 2.0), Point (1.0; 4.0), Point (5.0; 5.0)]

Through method I check identity lists:

private <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
        return new HashSet<>(list1).equals(new HashSet<>(list2));
    }

Why I get false when:

boolean result = listEqualsIgnoreOrder(expectedResult, actualResult);
8
  • 3
    Because of the contract of List.equals, as stated in its docs: they're not equal by that definition. Commented Aug 28, 2020 at 18:21
  • 4
    Java ArrayList - how can I tell if two lists are equal, order not mattering? Commented Aug 28, 2020 at 18:22
  • Because arrays aren't equal to each other. You'd have better luck with a List<List<Point>>. Commented Aug 28, 2020 at 18:24
  • 1
    The real point here is that equals for arrays doesn't work as you assume it would. If you would be using list of list of point things would be different. And note: mixing concepts is never a good approach. Either use arrays or lists, but lists of arrays is just weird. Commented Aug 28, 2020 at 18:25
  • 1
    You have no (good) reason to use Point[]. You're better off using List<Point>. So List<Point[]> would be List<List<Point>>. Commented Aug 28, 2020 at 18:33

1 Answer 1

1

These two lists have the same elements but in a different order:

List<Point[]> expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List<Point[]> expectedResult2 = Arrays.asList(combinationPoints2, combinationPoints1, combinationPoints3, combinationPoints4);

The List.equals method considers two lists to be equal if they contain the "same" elements in the same order. These two lists do have the same elements, but they are not in the same order. So the equals method must return false.

There's also a potential issue that stems from the fact that arrays don't implement equals method based on the contents: two different arrays instances with the same contents are not considered "equal" by the equals method. That doesn't come to into play here though: all of your arrays have different contents anyway.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.