基于新的List <myclass>集合更新List <myclass>集合</myclass> </myclass>

时间:2013-04-08 16:58:41

标签: java android arraylist

我需要以下列方式使用新的List集合更新List集合:

  • 原始列表从新列表中获取新项目
  • 原始列表中不在新列表中的项目将被删除

不幸的是,清除原始列表并从新列表重建它不是一个选项,因为那些已经包含具有重要值/引用的对象我不想丢失。

我需要实现的目标可归纳如下:

enter image description here

我提出'某种'解决方案'有点'有效,但我真的不喜欢它,我不确定这是多么有效......

class MyClass{
int someInt;
String someString;
int rowID; // DB reference, cannot lose it...
... 
}

public static List<MyClass> mergeMyClassLists(List<MyClass> origList, List<MyClass> newList){

    Integer index[]= new Integer[origList.size()];

    // Find the ones to remove from the old list
    int c=0;
    for(MyClass origMyClass:origList){       
       if(!hasMyClass(newList,origMyClass)) index[c] = origList.indexOf(origMyClass);
    c++;  
    }    

    // Then remove them
    for(int i:index){
    if(index[i]!=null)
        origList.remove(index[i]);
    }

    //Add new ones
    for(MyClass newMyClass:newList){        
        if(!hasMyClass(origList,newMyClass)) origList.add(newMyClass);      
    }           
return origList;
}

private static boolean hasMyClass(List<MyClass> myClassList, MyClass myClass){

    for(MyClass mc:myClassList){
        // Are they the same? based on my own criteria here
        if(mc.someInt == myClass.someInt && mc.someString.equals(myClass.someString)) return true; 
    }
    return false;
}

有没有更好/更标准的方法呢?我觉得我可能会让情况过于复杂......

4 个答案:

答案 0 :(得分:1)

覆盖equals中的hashCodeMyClass,以满足您的平等要求。

以下是一个例子:

public boolean equals(Object o) {
    if( !(o instanceof MyClass) ) return false;

    MyClass mc = (MyClass)o;
    if(this.someInt != mc.someInt)
        return false;
    return (this.someString == null)
            ? mc.someString == null
            : this.someString.equals(mc.someString);
}
public int hashCode() {
    int hashCode = someInt;
    if(someString != null)
        hashCode ^= someString.hashCode();
    return hashCode;
}

当你覆盖那些时,它就像这样简单:

origList.retainAll(newList);
newList.removeAll(origList);
origList.addAll(newList);

答案 1 :(得分:0)

按照你的要求,我猜你最重要的只是newList的元素。因此,您需要间接删除originalList的所有元素,并将newList的所有元素添加到originalList。所以我不应该做所有这些事情,而应该简单地写一下:

originalList = new ArrayList<MyClass>(newList);

答案 2 :(得分:0)

如果您希望丢失 originalList,则可能此代码可以提供帮助

List<String> orgList = new ArrayList<String>();
orgList.add("a");
orgList.add("b");

List<String> newList  = new ArrayList<String>();
newList.add("a");
newList.add("d");
newList.add("e");
newList.add("f");

List<String> result = new ArrayList<String>();
List<String> existingInBoth = new ArrayList<String>();
//Add item to result, if its present in newList BUT not in orgList
for(String s : newList) {
    if(!orgList.contains(s))
    result.add(s);
}
//Add the common items (this is inverse of removing the item which is there in orgList and not in newList)
for(String s : orgList) {
    if(newList.contains(s))
    existingInBoth.add(s);
}
result.addAll(existingInBoth);
System.out.println(result);

要使其适用于您的情况,您需要MyClass覆盖equals()类的java.lang.Object方法,并定义对象的相等。 原因是,contains(Object)方法通过检查对象的相等ob1.equals(obj2))来检查集合中对象的存在,包含集合中的所有元素。

equals()方法中的逻辑应与hasMyClass方法的if条件中的逻辑类似

答案 3 :(得分:0)

将项目放在HashSet中的NewList中。 (您可能需要在HashSet中使用自定义IEqualityComparer,具体取决于您如何在NewList中实例化对象 - 从OldList给定Object1,从NewList给出Object2,如果Object1 == Object2,您可以使用HashSet的默认构造函数,但是你'如果Object1!= Object2和Object1.equals(Object2),我需要创建一个自定义IEqualityComparer。)迭代OldList - 如果NewHashSet.contains(object)然后从NewHashSet中删除该对象,否则从OldList中删除该对象。接下来,遍历NewHashSet,并将剩余的对象添加到OldList。 HashSet.contains在或多或少的恒定时间内运行,因此整个合并方法将以线性时间运行。