我需要以下列方式使用新的List集合更新List集合:
不幸的是,清除原始列表并从新列表重建它不是一个选项,因为那些已经包含具有重要值/引用的对象我不想丢失。
我需要实现的目标可归纳如下:
我提出'某种'解决方案'有点'有效,但我真的不喜欢它,我不确定这是多么有效......
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;
}
有没有更好/更标准的方法呢?我觉得我可能会让情况过于复杂......
答案 0 :(得分:1)
覆盖equals
中的hashCode
和MyClass
,以满足您的平等要求。
以下是一个例子:
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在或多或少的恒定时间内运行,因此整个合并方法将以线性时间运行。