Сохраняет ли 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