比较两个数组列表对象的问题

Problems comparing two array lists objects

这似乎是一个愚蠢的问题,但我已经坚持了一段时间。我的代码应该检查两个数组列表是否相等,即使它们是乱序的。 boolean equals(Object other) Returns 如果给定对象是包含与 lineSegments 相同的线段的 LineSegmentDB,则为 true。到目前为止我有这个代码:

public boolean equals(Object other)
    {
//      Object lineSegments2 = new ArrayList<Object>();
//      lineSegments2 = other;

        if (!(other instanceof LineSegmentDB)) {
            return false;
        }
        ArrayList otherTest = (ArrayList) other;


        if(other.size() != lineSegments.size()){
            return false;
        }

        for(int i = 0; i < lineSegments.size(); i++){
            if(!(other.contains(lineSegments.get(i)))){
                return false;
            }
        }

        return true;
        //return lineSegments2;

    }

我确定 other 是 LineSegmentDB 的一个实例。然后我很确定我必须为其他人创建一个实例变量,所以我可以使用像 other.size() 或 other.get(i) 这样的东西。我认为该代码与我编写的其他一些代码类似,但无论我尝试什么都行不通,有什么建议吗?

其他代码:

ArrayList<LineSegment> union(LineSegmentDB other){
        ArrayList<LineSegment> lineSegments2 = new ArrayList<LineSegment>();
        lineSegments2 = other.lineSegments;


        for(int i = 0; i < other.size(); i++){
            if(hasPoint(other.getSegment(i))){
                System.out.println("Has Duplicate");
            }else{
                lineSegments.add(other.getSegment(i));
            }
        }
        return lineSegments;


    }

感谢您的帮助!

编辑,不确定这是否有帮助:

public class LineSegmentDB {
    public ArrayList<LineSegment> lineSegments = new ArrayList<LineSegment>();

    LineSegmentDB(){

    }

    public static void main(String[] args) {

        LineSegmentDB db = new LineSegmentDB();
        LineSegmentDB db2 = new LineSegmentDB();

        db.addLineSegment(new LineSegment(2,2,4,2));
        db.addLineSegment(new LineSegment(3,3,1,3));
        db.addLineSegment(new LineSegment(4,2,4,10));
        db2.addLineSegment(new LineSegment(4,2,2,2));
        db2.addLineSegment(new LineSegment(4,2,4,10));
        db2.addLineSegment(new LineSegment(3,3,3,1));
        System.out.println(db.equals(db2));


    }

我也知道粘贴大量代码很不酷,但也许它可能会回答一些我不能回答的问题。 http://pastebin.com/FUEsYA0n

再次感谢,你们真是救命恩人。

什么是LineSegmentDB?它是扩展了一些 List 实现还是实现了 List 接口本身?我想答案是

现在开始您的 equals() 方法:

if (!(other instanceof LineSegmentDB)) {
    return false;
}

这部分还可以。您首先正确检查给定对象是否与您的实例类型相同。

ArrayList otherTest = (ArrayList) other;
if(other.size() != lineSegments.size()){
    return false;
}

我猜你的 LineSegmentDB 根本不是 List。您的 class 必须实现 List 接口。这可以通过两种方式完成:

  • 自己实现接口 - implements List
  • 扩展一个已经实现接口的class - extends ArrayList

如果上述其中一项为真,您可以安全地将对象转换为 List,然后使用 size()contains() 方法。

希望这对您有所帮助:)

与其说是答案,不如说是猜测,但是..

在您的第一段代码中,您检查 other 是否属于 LineSegmentDb 类型,如果是,您将 other 转换为类型 ArrayList。你得到一个 java.lang.ClassCastException 因为 other 是 LineSegmentDb 类型,正如你检查的那样。 在您的第二段代码中,other.lineSegments 让我猜测 LineSegmentDb 对象具有 List<LineSegment> 属性。如果是这样,请尝试更改

if(other.lineSegments.size() != lineSegments.size()){
    return false;
}

for(int i = 0; i < lineSegments.size(); i++){
    if(!(other.contains(lineSegments.get(i)))){
        return false;
    }
}

if(((LineSegmentDB)other).lineSegments.size() != lineSegments.size()) {
    return false;
}

for(int i = 0; i < lineSegments.size(); i++){
    if(!(((LineSegmentDB)other).lineSegments
        .contains(lineSegments.get(i)))){
        return false;
    }
}

希望对您有所帮助。

如果不使用任何其他数据结构,使用列表检查集合相等性可能效率低下。

如果您有 2 个列表,listAlistB,检查它们是否具有相同元素的直观方法是为每个列表迭代 listB 中未标记的项目listA 中的元素。如果它们的长度相同,n,这是二次时间复杂度。

相反,您可以在 Java 中使用 HashMap。这是您的任务的快速伪代码:

// do proper null and size equality checks
Map<V, Integer> map = new HashMap<V, Integer>();
for (V v : listA) {
    int countSoFar = map.getOrDefault(v, 0);
    map.put(v, countSoFar + 1);
}

for (V v : listB) {
    int countSoFar = map.getOrDefault(v, 0);
    if (countSoFar == 0) {
        return false;
    }
    map.put(v, countSoFar - 1);
}

return checkIfAllValuesInMapEqualZero(map);

这主要是做什么的?它通过增加每个单独元素的计数器来记录第一个列表中每个元素的出现。然后,它减少第二个列表中每个元素的计数器。

如果 listB 中 1 类型的元素多于 listA,则在 listB 中使用完所有元素之前,该特定元素的计数器将达到 0,这表示 listA 中缺少某些内容,这表示它们不相同。
以类似的方式,listA 可能比 listB 具有更多的每个元素。如果是这种情况,至少地图中的一个条目的计数将 > 0。

  1. 您的 instanceof 测试仅在 LineSegmentDB 扩展 ArrayList 时才有效。 (或者你必须更正 instanceof 测试)
  2. contains 方法使用 LineSegmentequals 实现来比较两个实例是否是功能等价物。如果您没有覆盖 equalscontains 检查将只比较引用。