Наверное, немного перебор, но мне нравится такая изолированная проблема. :)
Этот код использует временную Set (для проверки уникальности), но удаляет элементы непосредственно в исходном списке. Поскольку удаление элементов внутри ArrayList может вызвать огромное количество копий массивов, метод remove (int) исключается.
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
Пока мы на нем, вот версия для LinkedList (много лучше всего!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Используйте интерфейс маркера для представления единого решения для List:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: Я думаю, что generics-stuff действительно не добавляет никаких Здесь. О, хорошо. :)