The best way to merge and remove duplicates from multiple lists in Java
I have a situation where I will receive 2 ArrayList < widget > I need to be able to merge all lists and delete any duplicate widgets so that I can only collect 1 ArrayList < widget > which contains all widgets in all merged lists without any duplication
Suppose the widget has an overridden equals method that can be used to determine whether two widgets are duplicate, although there may be a better method:
public ArrayList<Widget> mergeAndRemoveDupes(ArrayList<Widget> widgets...) { // ??? }
Find the most effective way to achieve this I am happy to use Apache commons or any other open source library that can help me! Thank you in advance!
Solution
For each ArrayList < widget >, add each element to set < widget > (HashSet or TreeSet, depending on whether they can be sorted in some way or hash), and use addall By default, the collection does not contain duplicates
If you need to end, you can convert this set to an array list
Note that if you decide to use HashSet, you will need to implement hashcode for your widget class, but if you have overridden equals, you should do so
Editor: here is an example:
//Either the class itself needs to implement Comparable<T>,or a similar //Comparable instance needs to be passed into a TreeSet public class Widget implements Comparable<Widget> { private final String name; private final int id; Widget(String n,int i) { name = n; id = i; } public String getName() { return name; } public int getId() { return id; } //Something like this already exists in your class @Override public boolean equals(Object o) { if(o != null && (o instanceof Widget)) { return ((Widget)o).getName().equals(name) && ((Widget)o).getId() == id; } return false; } //This is required for HashSet //Note that if you override equals,you should override this //as well. See: https://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java @Override public int hashCode() { return ((Integer)id).hashCode() + name.hashCode(); } //This is required for TreeSet @Override public int compareTo(Widget w) { if(id < w.getId()) return -1; else if(id > w.getId()) return 1; return name.compareTo(w.getName()); } @Override public String toString() { return "Widget: " + name + ",id: " + id; } }
If you want to use TreeSet but do not want to implement comparable < T > in your widget class, you can give the set itself a comparator object:
private Set<Widget> treeSet; .... treeSet = new TreeSet<Widget>(new Comparator<Widget>() { public int compare(Widget w1,Widget w2) { if(w1.getId() < w2.getId()) return -1; else if(w1.getId() > w2.getId()) return 1; return w1.getName().compareTo(w2.getName()); } });