为什么在Java中两个List<Object[]>不相等?

huangapple go评论71阅读模式
英文:

Why two List<Object[]> not equal in Java?

问题

以下是翻译好的部分:

我有一个名为`Point`的类其中重写了方法`equals()``hashCode()`:

```java
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) {
        // ...
    }

    @Override
    public int hashCode() {
        // ...
    }
}

我创建了一些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);

这是Point数组的组合:

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

创建List<Point[]>

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

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

比较两个List<Point[]>并得到结果true

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

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

expectedResult.equals(expectedResult2);    // TRUE

当我尝试改变顺序为:

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

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

在比较时,我得到false

expectedResult.equals(expectedResult2);    // FALSE

为什么?

更新 2020 年 8 月 29 日
我有两个List<Point[]>

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

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

内容如下:

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

[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));
}

// 第二个
[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)]

通过方法我检查了这两个列表是否相同:

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

为什么当我执行:

boolean result = listEqualsIgnoreOrder(expectedResult, actualResult);

我得到false

英文:

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&lt;Point[]&gt;:

List&lt;Point[]&gt; expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List&lt;Point[]&gt; expectedResult2 = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

Compare 2 List&lt;Point[]&gt; and get message true:

List&lt;Point[]&gt; expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List&lt;Point[]&gt; expectedResult2 = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

expectedResult.equals(expectedResult2);    // TRUE

When I'm try change order to this:

List&lt;Point[]&gt; expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List&lt;Point[]&gt; 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&lt;Point[]&gt;:

// FIRST
List&lt;Point[]&gt; expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

and

List&lt;Point[]&gt; 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 &lt;T&gt; boolean listEqualsIgnoreOrder(List&lt;T&gt; list1, List&lt;T&gt; list2) {
        return new HashSet&lt;&gt;(list1).equals(new HashSet&lt;&gt;(list2));
    }

Why I get false when:

boolean result = listEqualsIgnoreOrder(expectedResult, actualResult);

答案1

得分: 1

这两个列表具有相同的元素,但顺序不同:

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

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

List.equals 方法认为如果两个列表包含相同顺序的 "相同" 元素,则它们相等。这两个列表确实具有相同的元素,但顺序不同。因此,equals 方法必须返回 false

还有一个潜在的问题,这源于数组不基于内容实现 equals 方法:具有相同内容的两个不同数组实例不被 equals 方法视为 "相等"。但在这种情况下并不适用:你的所有数组无论如何都具有不同的内容。

英文:

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

List&lt;Point[]&gt; expectedResult = Arrays.asList(combinationPoints1, combinationPoints2, combinationPoints3, combinationPoints4);

List&lt;Point[]&gt; 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.

huangapple
  • 本文由 发表于 2020年8月29日 02:17:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63639018.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定