1

我正在尝试复制一个ArrayList,但它似乎只是引用它而不是真正复制它。

我的代码:

List<Column> columns = columnData(referencedField.table);
List<Field> newPath = new ArrayList<>(startPath);
System.out.println("Equals? " + (newPath.equals(startPath)));

startPath是一个ArrayList<Field>被传递到函数中。

场地:

public class Field 
{
    public String table;
    public String column;

    public Field(final String table, final String column) {
        this.table = table;
        this.column = column;
    }

    @Override
    public String toString() {
        return "(" + table + ", " + column + ")";
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 67 * hash + Objects.hashCode(this.table);
        hash = 67 * hash + Objects.hashCode(this.column);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Field other = (Field) obj;
        if (!Objects.equals(this.table, other.table)) {
            return false;
        }
        if (!Objects.equals(this.column, other.column)) {
            return false;
        }
        return true;
    }
}

现在我已经阅读了有关克隆它的信息,但我没有这方面的经验。我实际上想知道克隆是否真的会创建一个新对象列表,使得它们不再相等,因为相同的内容元素将相等。

所以换个说法,我想要的是:确保startPathnewPath不相等,因此不相互引用,因为我正在使用 Lists 一个递归函数,应该将列表添加到地图中。

4

2 回答 2

3

你需要做一个深拷贝。

List<Field> newPath = new ArrayList<>();
for(Field field: startPath){
   newPath.add(field.clone());
}
于 2013-07-10T08:38:22.563 回答
1

如果您在类中使用重写的 equals 方法而不是引用相等,则复制的集合将等于原始集合:-)。

如果您正确覆盖了 equals 方法,则无法避免这种情况。无论您如何克隆或复制它,它们仍然是相同的..

让我详细说明。

List<Field> newPath = new ArrayList<>(startPath);

startPath很好的复制内容。它调用本机函数来复制内部数组,因此请放心,您的对象是深度复制的。

问题在于方法ArrayListequals工作方式。好吧,这不是问题,这是正确的方法,但这就是在这种特定情况下您没有得到平等的原因。

你打电话时

newPath.equals(startPath)

它将遍历元素并使用它们的equals方法比较所有元素。如果元素类型的 equals 方法被覆盖以考虑它的状态而不是默认的引用相等(就像您的Field类的情况一样),那么两个列表中的所有元素都是相等的。

因为它们的数据是相等的,即使它们不是相同的对象。

于 2013-07-10T08:38:16.657 回答