Issue
I have an ArrayList of Device objects. I want to remove duplicate entries.
The device objects has three fields: id, name, and status. If an id occurs multiple times, I need to check the status of each duplicate id and filter it based on the below criteria.
There can be 3 status i.e. New, Pending, Complete.
- If a duplicate id has a status as Complete then keep that object and remove all other object for this id having any other status.
- If duplicate id does not have a status as Complete then check for status Pending and keep that and remove any other occurrence for that id in the list.
Device class -:
class Device {
long id
String name
String status
@Override
String toString() {
return "Device [${Id}, ${status}]"
}
}
Sample data:
[
[id : 11, name:'test', status:'pending'],
[id : 13, name : 'abc', status:'new'],
[id : 14, name : 'xyz', status:'pending'],
[id : 11, name : 'test', status:'new'],
[id : 15, name : 'wxy', status:'complete'],
[id : 15, name : 'wxy', status:'pending']
]
Expected output:
[
[id : 11, name:'test', status:'pending'],
[id : 13, name : 'abc', status:'new'],
[id : 14, name : 'xyz', status:'pending'],
[id : 15, name : 'wxy', status:'complete'],
]
Can someone here help with this logic possibly in Groovy or else in Java?
Solution
I would use Groovy's groupBy
/sort
combo to achieve what you want:
class Device {
long id
String name
String status
@Override
String toString() { "Device [$id, $status]" }
}
def devices = [
[id : 11, name:'test', status:'pending'],
[id : 13, name : 'abc', status:'new'],
[id : 14, name : 'xyz', status:'pending'],
[id : 11, name : 'test', status:'new'],
[id : 15, name : 'wxy', status:'complete'],
[id : 15, name : 'wxy', status:'pending']
].collect{ it as Device }
def result = devices.groupBy{ it.id }.findResults{ id, devs ->
devs.sort{ [ 'complete', 'pending', 'new' ].indexOf it.status }.first()
}
assert result.toString() == '[Device [11, pending], Device [13, new], Device [14, pending], Device [15, complete]]'
Answered By - injecteer