Какой список будет автоматически удалять дубликаты при их добавлении.
например. для списка, если я добавлю 1,2,3,4,5,1,2,3 = Список должен содержать всего 1,2,3,4,5
Какой список будет автоматически удалять дубликаты при их добавлении.
например. для списка, если я добавлю 1,2,3,4,5,1,2,3 = Список должен содержать всего 1,2,3,4,5
Посмотрите LinkedHashSet
Набор автоматически удалит дубликаты, но это коллекция, а не список.
Я не думаю, что есть список, который устраняет дубликаты в стандартной библиотеке.
Если вы хотите удалить дубликаты, используйте Set
Как и в вышеупомянутом плакате, нет списка с уникальной обработкой.
Посмотрите Список (платформа Java SE 6)
В отличие от наборов, списки обычно позволяют дублировать элементы. Более формально списки обычно допускают пары элементов e1 и e2, такие как e1.equals(e2), и они обычно допускают множество нулевых элементов, если они разрешают нулевые элементы вообще. Не исключено, что кто-то может пожелать реализовать список, который запрещает дублирование, путем исключения исключений во время выполнения, когда пользователь пытается их вставить, но мы ожидаем, что это использование будет редкими.
Вы можете расширить существующий java.util.ArrayList
и инкапсулировать a java.util.Set
в нем. Вы должны переопределить все методы add(...)
, addAll(...)
и remove
и сначала проверить, находится ли элемент в инкапсулированном наборе (в случае добавления его в список):
public class ListSet<E> extends ArrayList<E> {
private Set<E> set;
public ListSet() {
set = new HashSet<E>();
}
@Override
public boolean add(E element) {
if(set.add(element)) {
super.add(element);
return true;
}
return false;
}
// other add and remove methods
}
ИЗМЕНИТЬ
Как отметил @Alnitak: не забудьте синхронизировать ваш HashSet для поддержки всякий раз, когда элемент удален.
Вы хотите, чтобы Set, например, HashSet(), а не список? No List не удаляет дубликаты, по определению списки разрешают их.
Не нужно, как и кто-то предлагал, реализовать собственный список, который выполняет повторную проверку и возвращает false, если в add() есть дубликат.
Почему? Поскольку вы нарушите договор интерфейса List, в котором говорится:
public boolean add(E e)
[...]
Returns:
true (as specified by Collections.add())
List.add(E e) ДОЛЖЕН вернуть значение true и добавить элемент в список или вызвать исключение. Списки не предназначены для повторных проверок, это то, на что рассчитаны.
В то время вы можете создать свой собственный класс и @Override
добавить метод в свой класс.
"просто посмотри мой код и попрактикуйся"
import java.util.ArrayList;
import java.util.List;
class MyList extends ArrayList<Integer> {
private static final long serialVersionUID = 1L;
@Override
public boolean add(Integer element) {
if (!found(element)) {
super.add(element);
}
return false;
}
public boolean found(Integer e) {
return equals(e);
}
public boolean equals(Integer e) {
for (int i = 0; i < super.size(); i++) {
if (super.get(i).equals(e))
return true;
}
return false;
}
}
public class ListRemovingDuplicated {
public static void main(String[] abd) {
List<Integer> obj = new MyList();
obj.add(10);
obj.add(20);
obj.add(10);
obj.add(10);
obj.add(30);
System.out.println(obj);
}
}
Вот расширение ArrayList, которое отклоняет дубликаты:
public class NoDupeList<E> extends ArrayList<E>{
private static final long serialVersionUID = -2682691450003022201L;
public NoDupeList(){
super();
}
public NoDupeList(final Collection<? extends E> c){
super(c instanceof Set<?> ? c : new LinkedHashSet<E>(c));
}
public NoDupeList(final int initialCapacity){
super(initialCapacity);
}
@Override
public boolean add(final E e){
return !this.contains(e) && super.add(e);
};
@Override
public boolean addAll(final Collection<? extends E> c){
final List<E> intermediate = new ArrayList<E>(c);
intermediate.removeAll(this);
return super.addAll(intermediate);
}
@Override
public void add(final int index, final E element){
if(!this.contains(element)){
super.add(index, element);
}
};
@Override
public E set(final int index, final E element){
if(this.contains(element) && !this.get(index).equals(element)){
throw new IllegalArgumentException("This would cause a duplicate");
}
return super.set(index, element);
};
}
Единственное, с чем я не могу справиться, это метод set(). Мое решение состоит в том, чтобы выбросить IllegalArgumentException
, если это приведет к дублированию, но, возможно, обычно следует использовать этот метод вместо UnsupportedOperationException
.
В любом случае, здесь тестовый метод:
@Test
public void testNoDupeList() throws Exception{
final List<String> list =
new NoDupeList<String>(Arrays.asList("abc", "def", "abc"));
assertEquals(list, Arrays.asList("abc", "def"));
list.addAll(Arrays.asList("abc", "def", "ghi"));
assertEquals(list, Arrays.asList("abc", "def", "ghi"));
try{
list.set(2, "abc");
fail("This should have caused an Exception");
} catch(final Exception e){}
};
Самый простой способ получить фактический List
, который отсортирован и не имеет дубликатов, состоял бы в том, чтобы обернуть его следующим образом:
List<Integer> unique =
new ArrayList<Integer>(new TreeSet<Integer>(Arrays.asList(1, 1, 2, 2, 3, 3)));
Обратите внимание, что при добавлении в этот список дубликаты не будут устранены, но, возможно, это сработает для вас.