Я пытаюсь найти реализацию java.util.List
и java.util.Set
одновременно на Java. Я хочу, чтобы этот класс разрешал только уникальные элементы (как Set
) и сохранял их порядок (например List
). Он существует в JDK 6?
Это важно, List<T>#add(int, T)
чтобы я мог вставлять в определенную позицию.
java
collections
Егор256
источник
источник
Comparator
? Также вам нужна семантикаList
интерфейса?Ответы:
TreeSet
сортируется по порядку элементов;LinkedHashSet
сохраняет порядок размещения. Надеюсь, один из них - то, что вам нужно.Вы указали, что хотите иметь возможность вставлять в произвольное место, я подозреваю, что вам придется написать свое собственное - просто создайте класс, содержащий a
HashSet<T>
и anArrayList<T>
; при добавлении элемента проверьте, есть ли он в наборе, прежде чем добавлять его в список.В качестве альтернативы общие коллекции Apache4 предлагают
ListOrderedSet
иSetUniqueList
, которые ведут себя аналогичным образом и должны соответствовать заданным требованиям.источник
LinkedHashSet - это ответ.
Порядок итераций и уникальность.
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
источник
List
интерфейс, см. Мои изменения в вопросеВы имеете ввиду нравится
LinkedHashSet
? Это сохраняет порядок ввода, но не допускает дублирования.IMHO, это необычное требование, но вы можете написать список без дубликатов.
class SetList<T> extends ArrayList<T> { @Override public boolean add(T t) { return !super.contains(t) && super.add(t); } @Override public void add(int index, T element) { if (!super.contains(element)) super.add(index, element); } @Override public boolean addAll(Collection<? extends T> c) { boolean added = false; for (T t : c) added |= add(t); return added; } @Override public boolean addAll(int index, Collection<? extends T> c) { boolean added = false; for (T t : c) if (!super.contains(t)) { super.add(index++, t); added = true; } return added; } }
источник
List
интерфейс, см. Мои изменения в вопросеO(n)
сложности вставки, есть компромисс между двойным хранением иO(log(n))
операцией вставки.Невозможно реализовать
List
иSet
сразу без нарушения договора. См., Например,Set.hashCode
договор:С другой стороны, вот договор
List.hashCode
:Таким образом, невозможно реализовать один класс, который гарантирует выполнение обоих контрактов. Та же проблема для
equals
реализации.источник
Если вы не ограничиваетесь JDK 6, вы можете использовать общую библиотеку коллекций Apache, которая предлагает точное соответствие вашим потребностям - ListOrderedSet . Это вроде
List
иSet
совмещено вместе :)источник
List
интерфейсУ меня была похожая проблема, поэтому я написал свою. Смотрите здесь .
IndexedArraySet
РаспространяетсяArrayList
и инвентарьSet
, поэтому он должен поддерживать все операции , которые вам нужны. Обратите внимание, что вставка элементов в места в серединеArrayList
может быть медленной для больших списков, потому что все следующие элементы необходимо переместить. МойIndexedArraySet
не меняет этого.источник
Другой вариант (без
List
требования к интерфейсу) - это GuavaImmutableSet
, который сохраняет порядок вставки. Со своей вики-страницы :источник