Сохраняет ли Java-набор порядок? Метод возвращает мне Set, и, предположительно, данные упорядочены, но итерируя по Set, данные неупорядочены. Есть ли лучший способ справиться с этим? Нужно ли менять метод, чтобы он возвращал что-то отличное от Set?
Сохраняет ли Java-набор порядок? Метод возвращает мне Set, и, предположительно, данные упорядочены, но итерируя по Set, данные неупорядочены. Есть ли лучший способ справиться с этим? Нужно ли менять метод, чтобы он возвращал что-то отличное от Set?
Ответы:
Set
Интерфейс не дает никаких гарантий заказа.
Его подчиненный интерфейс SortedSet
представляет собой набор, отсортированный по некоторому критерию. В Java 6 есть два стандартных контейнера, которые реализуют SortedSet
. Они есть TreeSet
и ConcurrentSkipListSet
.
Помимо SortedSet
интерфейса есть еще и LinkedHashSet
класс. Он запоминает порядок, в котором элементы были вставлены в набор, и возвращает его элементы в этом порядке.
LinkedHashSet - это то, что вам нужно.
List
не является Set
(это не гарантирует уникальность членства).
Поскольку многие из участников предложили использовать LinkedHashSet, чтобы сохранить порядок коллекции. Вы можете обернуть ваш набор с помощью этой реализации.
Реализация SortedSet может использоваться для сортированного порядка, но для вашей цели используйте LinkedHashSet .
Также из документов,
«Эта реализация избавляет своих клиентов от неуказанного, обычно хаотического порядка, предоставляемого HashSet, без увеличения стоимости, связанного с TreeSet. Его можно использовать для создания копии набора, который имеет тот же порядок, что и оригинал, независимо от оригинала реализация набора: "
Источник: http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
Набор это просто интерфейс. Чтобы сохранить порядок, вы должны использовать конкретную реализацию этого интерфейса и подчиненного интерфейса SortedSet, например TreeSet или LinkedHashSet. Вы можете обернуть ваш набор следующим образом:
Set myOrderedSet = new LinkedHashSet(mySet);
Вот краткий обзор характеристик порядка стандартных Set
реализаций, доступных в Java:
Для вашего конкретного случая вы можете сначала отсортировать элементы, а затем использовать любой из 1 или 2 (наиболее вероятно, LinkedHashSet
или TreeSet
). Или, альтернативно и более эффективно , вы можете просто добавить несортированные данные в папку, TreeSet
которая автоматически позаботится о сортировке.
Для сохранения заказа используйте List
или LinkedHashSet
.
LinkedHashSet
не ... Map
.
LinkedHashSet - это упорядоченная версия HashSet, которая поддерживает двусвязный список для всех элементов. Используйте этот класс вместо HashSet, если вам важен порядок итераций.
Из Javadoc для Set.iterator()
:
Возвращает итератор для элементов в этом наборе. Элементы возвращаются в произвольном порядке (если этот набор не является экземпляром некоторого класса, который предоставляет гарантию).
И, как уже заявлено shuuchan , a TreeSet
является реализацией, Set
которая имеет гарантированный порядок:
Элементы упорядочиваются с использованием их естественного упорядочения или с помощью компаратора, предоставляемого во время создания набора, в зависимости от того, какой конструктор используется.
Обычно установленный не сохраняет порядок, такой как HashSet, чтобы быстро найти изумруд, но вы можете попробовать LinkedHashSet, он сохранит порядок, в который вы положили.
Сам интерфейс Set не предусматривает какого-либо конкретного порядка. SortedSet делает однако.
Итератор, возвращаемый Set, не должен возвращать данные Упорядоченным способом. Посмотрите это Два java.util.Iterators к одной коллекции: они должны возвращать элементы в том же порядке?
Только SortedSet
может сделать заказSet