Нет никакого набора Java в стандартной библиотеке, чтобы сделать это. LinkedHashSet<E>
консервы, заказывающие так же List
, тем не менее, поэтому при обертывании набора в List
, когда Вы хотите использовать его в качестве List
, Вы получите семантику, которую Вы хотите.
, С другой стороны, эти Наборы палаты общин (или commons-collections4
, для универсальной версии) имеет List
, который делает то, что Вы уже хотите: SetUniqueList
/ SetUniqueList<E>
.
Таким образом, вот то, что я сделал в конечном счете. Я надеюсь, что это помогает кому-то еще.
class NoDuplicatesList<E> extends LinkedList<E> {
@Override
public boolean add(E e) {
if (this.contains(e)) {
return false;
}
else {
return super.add(e);
}
}
@Override
public boolean addAll(Collection<? extends E> collection) {
Collection<E> copy = new LinkedList<E>(collection);
copy.removeAll(this);
return super.addAll(copy);
}
@Override
public boolean addAll(int index, Collection<? extends E> collection) {
Collection<E> copy = new LinkedList<E>(collection);
copy.removeAll(this);
return super.addAll(index, copy);
}
@Override
public void add(int index, E element) {
if (this.contains(element)) {
return;
}
else {
super.add(index, element);
}
}
}
Необходимо серьезно рассмотреть ответ dhiller:
new ArrayList(set)
(или new LinkedList(set)
, безотносительно). я думаю, что решение, которое Вы отправили с эти NoDuplicatesList
, имеет некоторые проблемы, главным образом с contains()
, метод, плюс Ваш класс не обрабатывает проверку дубликаты в Наборе, переданном Вашему addAll()
метод.
Почему бы не инкапсулировать набор со списком, видом как:
new ArrayList( new LinkedHashSet() )
Это оставляет другую реализацию для кого-то, кто настоящее ведущее устройство Наборов;-)
в документации для интерфейсов набора говорится:
Набор — набор, который не может содержать дублирующиеся элементы.
Список — заказанный набор (иногда названный последовательностью). Списки могут содержать дублирующиеся элементы.
Поэтому, если Вы не хотите дубликаты, Вы, вероятно, не должны использовать список.
Первое, что пришло на ум списки позволяют дубликаты. Вы могли быстро реализовать UniqueArrayList
и переопределить весь add
/ insert
функции для проверки на contains()
перед вызовом унаследованных методов. Для персонального использования Вы могли только реализовать add
метод, который Вы используете и переопределяете другие для выдачи исключения в случае, если будущие программисты пытаются использовать список другим способом.
Мне что-то нужно вот так, поэтому я пошел в общие коллекции и использовал SetUniqueList, но когда я провел некоторый тест производительности, я обнаружил, что он не оптимизирован по сравнению со случаем, если я хочу использовать Set и получить массив с помощью Set.toArray (), SetUniqueTest занял время 20: 1 для заполнения, а затем прохождения 100000 строк по сравнению с другой реализацией, что является большой разницей, поэтому, если вы беспокоитесь о производительности,Я рекомендую вам использовать Set и получить массив вместо использования SetUniqueList, если вам действительно не нужна логика SetUniqueList, тогда вам нужно проверить другие решения ...
Основной метод кода тестирования:
public static void main (String [] args) {
SetUniqueList pq = SetUniqueList.decorate(new ArrayList());
Set s = new TreeSet();
long t1 = 0L;
long t2 = 0L;
String t;
t1 = System.nanoTime();
for (int i = 0; i < 200000; i++) {
pq.add("a" + Math.random());
}
while (!pq.isEmpty()) {
t = (String) pq.remove(0);
}
t1 = System.nanoTime() - t1;
t2 = System.nanoTime();
for (int i = 0; i < 200000; i++) {
s.add("a" + Math.random());
}
s.clear();
String[] d = (String[]) s.toArray(new String[0]);
s.clear();
for (int i = 0; i < d.length; i++) {
t = d[i];
}
t2 = System.nanoTime() - t2;
System.out.println((double)t1/1000/1000/1000); //seconds
System.out.println((double)t2/1000/1000/1000); //seconds
System.out.println(((double) t1) / t2); //comparing results
}
С уважением Мохаммед Слим http://abusleem.net/blog