Reputation: 1122
I wasn't sure how exactly to word the title but this is the situation. I have 2 lists, DBList
is a list of DB values and NewList
is the new list of values to be stored in the DB. Now the tricky part is that I am only adding values to DBList
that don't already exist, BUT if DBList
contains values that NewList
doesn't then i want to remove them
Essentially, NewList
becomes DBList
but i want to retain all the applicable previously existing data in DBList
that is already persisted to the database
This is what I have and it works, but I want to know if there is a better way to do it.
List<DeptMajors> DBList;
List<DeptMajors> NewList;
for(DeptMajors dm : NewList) {
if(!DBList.contains(dm)) {
DBList.add(dm);
}
}
Iterator<DeptMajors> i = DBList.iterator();
while(i.hasNext()) {
DeptMajors dm = i.next();
if(!NewList.contains(dm)) {
i.remove()
}
}
So the first loops puts all data from NewList
into DBList
that doesn't already exist. Then the next loop will check if DBList
contains data that doesn't exist in NewList
and removes it from DBList
Upvotes: 2
Views: 117
Reputation: 171164
Ok, so I had to make up a DeptMajors
class:
import groovy.transform.*
@TupleConstructor
@ToString(includeNames=true)
@EqualsAndHashCode(includes=['id'])
class DeptMajors {
int id
String name
int age
}
This class is equal if the id
matches (and no other fields)
We can then make a dbList
(lower case initial char for variables, else Groovy can sometimes get confused and think it's a class)
def dbList = [
new DeptMajors(1, 'tim', 21),
new DeptMajors(2, 'raymond', 20)
]
And a newList
which contains an updated raymond
(which will be ignored), a new entry alice
(which will be added) and no tim
(so that will be removed)
def newList = [
new DeptMajors(2, 'raymond', 30),
new DeptMajors(3, 'alice', 28)
]
We can then work out our new merged list. This is the intersection of dbList
and newList
(so we keep raymond
in the original state), added to the new elements in newList
which can be found by taking dbList
away from it:
def mergedList = dbList.intersect(newList) + (newList - dbList)
This give the result I think you want?
assert mergedList == [
new DeptMajors(2, 'raymond', 20), // unchanged
new DeptMajors(3, 'alice', 28) // new entry (tim is removed)
]
Or as BZ says in the comments, you could also use:
def mergedList = newList.collect { e -> dbList.contains(e) ? dbList.find { it == e }: e}
Or the shorter:
def mergedList = newList.collect { e -> dbList.find { it == e } ?: e}
Upvotes: 2