I have two lists. They contain objects of different types, but both types contain id and name, and id is what I am comparing on. List one is fetched from DB, and list two is sent from frontend.
What I need to do is loop through them and find which list item is newly added and which one was deleted.
I was able to do it, but the problem is that it look ugly.
Let's say I have a object that is called NameDTO which can have id and name. List two is filled with that type of objects.
This is how I did it:
final ArrayList<NamedDTO> added = new ArrayList<>();
final ArrayList<NamedDTO> removed = new ArrayList<>();
for(NamedDTO listTwoObject : listTwo) {
boolean contained = false;
for(SomeObject listOneObject : listOne) {
if(listTwoObject.getId().equals(listOneObject.getId()) {
contained = true;
}
}
if(!contained) {
added.add(listTwoObject);
}
}
for(SomeObject listOneObject : listOne) {
boolean contained = false;
for(NamedDTO listTwoObject : listTwo) {
if(listTwoObject.getId().equals(listOneObject.getId()) {
contained = true;
}
}
if(!contained) {
removed.add(new NamedDTO(listOneObject.getId(), listOneObject.getName()));
}
}
This works, I have tested it. Are there better solutions? I was thinking of using Sets so I can compare them, Is there a downside to that ?
Using the Java List API. We can create a copy of one list and then remove all the elements common with the other using the List method removeAll(): List<String> differences = new ArrayList<>(listOne); differences. removeAll(listTwo); assertEquals(2, differences.
sort() and == operator. The list. sort() method sorts the two lists and the == operator compares the two lists item by item which means they have equal data items at equal positions. This checks if the list contains equal data item values but it does not take into account the order of elements in the list.
Java provides a method for comparing two Array List. The ArrayList. equals() is the method used for comparing two Array List. It compares the Array lists as, both Array lists should have the same size, and all corresponding pairs of elements in the two Array lists are equal.
If I understand correctly, this is the example scenario:
[A, B, C, D]
[B, C, D, E, F]
and what you need to get as an effect is:
[E, F]
[A]
First thing first, I would use some type adapter or extend the different types from one common class and override
the equals
method so you can match them by id
and name
Secondly, this is very easy operations on sets (you could use set's but list are fine too). I recommend using a library: https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html
And now basically:
listTwo - listOne
listOne - listTwo
and using java code:
CollectionUtils.removeAll(listTwo, listOne)
CollectionUtils.removeAll(listOne, listTwo)
Otherwise, all collections implementing Collection
(Java Docs) also has removeAll
method, which you can use.
I propose solution using java 8 streams:
ArrayList<ObjOne> list = new ArrayList<>(Arrays.asList(new ObjOne("1","1"),new ObjOne("3","3"),new ObjOne("2","2")));
ArrayList<ObjTwo> list2 = new ArrayList<>(Arrays.asList(new ObjTwo("1","1"),new ObjTwo("3","3"),new ObjTwo("4","4")));
List<ObjOne> removed = list.stream().filter(o1 -> list2.stream().noneMatch(o2 -> o2.getId().equals(o1.getId())))
.collect(Collectors.toList());
System.out.print("added ");
removed.forEach(System.out::println);
List<ObjTwo> added = list2.stream().filter(o1 -> list.stream().noneMatch(o2 -> o2.getId().equals(o1.getId())))
.collect(Collectors.toList());
System.out.print("removed ");
added.forEach(System.out::println);
This is basically your solution but implemented using streams, which will make your code shorter and easer to read
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With