Лучший способ объединить и удалить дубликаты из нескольких списков в Java
у меня есть ситуация, когда я буду получать 2+ ArrayList<Widget>
и мне нужно иметь возможность объединить все списки и удалить любой дубликат Widget
Так что я получаю только 1 ArrayList<Widget>
, который содержит все Widget
s из всех объединенных списков, но без каких-либо дубликатов.
предположим Widget
был переопределен equals
метод can используется для определения, являются ли два Widget
s являются дубликатами, хотя может быть лучше так:
public ArrayList<Widget> mergeAndRemoveDupes(ArrayList<Widget> widgets...) {
// ???
}
просмотр для наиболее алгоритмически эффективного способа выполнения этого. Я рад использовать Apache Commons или любые другие библиотеки с открытым исходным кодом, которые тоже помогут мне! Заранее спасибо!
3 ответов
для каждого ArrayList<Widget>
добавить каждый элемент Set<Widget>
(HashSet
или TreeSet
, в зависимости от того, могут ли они быть заказаны каким-либо образом или хэшируются), используя addAll
. По умолчанию наборы не содержат дубликатов.
вы можете преобразовать это Set
обратно в (Array)List
если вам нужно в конце.
Примечание вам нужно будет реализовать hashCode
для Widget
класс если вы решили использовать HashSet
, но если у вас есть переопределенный equals,
вы должны сделать это в любом случае.
Edit: вот пример:
//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: http://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;
}
}
если вы хотите использовать TreeSet
но не хочу, чтобы реализовать Comparable<T>
на Widget
класс, вы можете дать самому набору
Я бы сделал это так
Set<Widget> set = new HashSet<>(list1);
set.addAll(list2);
List<Widget> mergeList = new ArrayList<>(set);
использовать Set
Коллекция Класс
ArrayList<Widget> mergeList = new ArrayList<widget>();
mergeList.addAll(widgets1);
mergeList.addAll(widgets2);
Set<Widget> set = new HashSet<Widget>(mergeList);
ArrayList<Widget> mergeListWithoutDuplicates = new ArrayList<widget>();
mergeListWithoutDuplicates .addAll(set);
return mergeListWithoutDuplicates;
теперь здесь Set удалит все значения дубликатов из вашего ArrayList.