5

我有一个我在屏幕上显示的对象列表。用户可以随意更改它们,然后点击提交。在提交方法中,我将存储的原始列表和当前列表进行比较。我必须创建第三个列表,其中包含使用操作代码添加、删除或更改的所有对象,以指定它是什么。对象有一个 id 来识别它们,默认为 0。

我怎样才能做到这一点?这是我能想到的最好的(伪代码),但它看起来很草率。

for (currentObject : objects in current list)
    if (currentObject.id is 0)
        //Was added
    for (oldObject : objects in original list)
        if (currentObject.id == oldObject.id)
            //Existed - compare other fields to see if changed

for (oldObject1 : objects in original list)
    boolean existed = false;
    for (currentObject1 : objects in current list)
        if(oldObject1.id == currentObject1.id)
            existed=true;
    if (!existed)
        //Was removed
4

2 回答 2

6

如果排序无关紧要并且您只关心元素是添加还是删除,您可能需要考虑更改数据结构并使用Set而不是List. 该Set类型专门用于确定元素是否存在并有效地执行此操作,但代价是您不再记住元素的顺序。

例如,使用HashSet,您可以执行以下操作:

Set<T> oldElems = new HashSet<T>(originalList);
Set<T> newElems = new HashSet<T>(currentList);

for (T obj : oldElems) {
    if (!newElems.contains(obj)) {
        /* ... this object was removed ... */
    }
}

for (T obj : newElems) {
    if (!oldElems.contains(obj)) {
        /* ... this object was added ... */
    }
}

希望这可以帮助!

于 2013-06-19T19:04:58.733 回答
3

您可以通过一个循环来完成,通过不断维护 3 路结果列表。如果您可以覆盖equals()以依赖ids,那很好。如果没有,请检查update下的代码。

这是代码,请参阅下面的说明:

List<T> origList = ...;
List<T> newList = ...;

List<T> addedList = new ArrayList<T>();
List<T> deletedList = new ArrayList<T>();
List<T> changedList = new ArrayList<T>();

deletedList.addAll(origList);

for(T t : newList) {
    int origIndex = deletedList.indexOf(t);
    if (origIndex < 0) {
        addedList.add(t);
    } else {
        T origT = deletedList.remove(origIndex);
        if(t.compareTo(origT) != 0) {
            changedList.add(t);
        }
    }
}

请注意,我假设equals()将检查id,compareTo()并将检查所有其他字段。

解释:

deletedList您从中删除了也存在于中的所有元素newList,因此结果是已删除的项目。

您将所有新元素添加到addedList原始列表中不存在的元素中。

如果两者都存在并且对象不同,则它们将转到changedList.

如果两者都存在并且对象相同,那么我们不会在任何地方添加它。

笔记:

如果新对象的 ID 为0,它们将不会出现origList(因为我们假设它们已经被创建)。

当我上次实现这个时,我创建了一个单独的方法来逐字段比较对象,所以我可以将比较逻辑与标准 Java 方法分开(实际上它也是在 上声明的interface

我用Lists 创建了它,但实际上你可以将它与任何类型的Collection. 与 List 一起使用将保留原始顺序。

更新:

尝试equals以这种方式覆盖您的(我跳过了类型检查和强制转换):

public boolean equals(T other) {
    if (this.id == 0) {
        return this == other;
    }
    return this.id == other.id;
}

尚未创建的实例仅与它们自己相等。已经创建的通过 id 检查。

于 2013-06-19T19:15:44.973 回答