英文:
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<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);
答案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<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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论