В Java есть такие SortedSet
и SortedMap
интерфейсы. Оба принадлежат платформе Java Collections и предоставляют отсортированный способ доступа к элементам.
Тем не менее, в моем понимании нет SortedList
в Java. Вы можете использовать java.util.Collections.sort()
для сортировки списка.
Есть идеи, почему он так устроен?
java
sorting
collections
Jijoy
источник
источник
int diff = this.score - that.score;
return (diff == 0) ? 1 : diff;
Поскольку это вонючий взлом, я бы предоставил это как аргумент анонимного конструктора, а не как реализующий Comparable.Ответы:
Итераторы списка гарантируют, прежде всего, то, что вы получите элементы списка во внутреннем порядке списка (он же порядок вставки ). Точнее, в том порядке, в котором вы вставили элементы, или о том, как вы манипулировали списком. Сортировка может рассматриваться как манипулирование структурой данных, и существует несколько способов сортировки списка.
Я закажу пути в порядке полезности, как лично вижу:
1. Рассмотрите возможность использования
Set
илиBag
коллекции вместоПРИМЕЧАНИЕ: я поставил эту опцию сверху, потому что это то, что вы обычно хотите делать в любом случае.
Сортированный набор автоматически сортирует коллекцию при вставке , что означает, что он выполняет сортировку при добавлении элементов в коллекцию. Это также означает, что вам не нужно сортировать вручную.
Кроме того, если вы уверены, что вам не нужно беспокоиться о (или иметь) дубликаты элементов, вы можете использовать
TreeSet<T>
вместо этого. Он реализуетSortedSet
иNavigableSet
интерфейсы и работает , как вы, вероятно , планирующие из списка:Если вы не хотите естественного упорядочения, вы можете использовать параметр конструктора, который принимает
Comparator<T>
.В качестве альтернативы, вы можете использовать Multisets (также известный как Bags ) , то есть,
Set
который позволяет дублировать элементы, и есть их сторонние реализации. В частности, из библиотек Guava естьTreeMultiset
, который работает так же, какTreeSet
.2. Сортируйте свой список с помощью
Collections.sort()
Как упоминалось выше, сортировка
List
s - это манипулирование структурой данных. Так что для ситуаций, когда вам нужен «один источник правды», который будет отсортирован различными способами, тогда сортировка вручную - это путь.Вы можете отсортировать свой список с помощью
java.util.Collections.sort()
метода. Вот пример кода о том, как:Использование компараторов
Одно очевидное преимущество заключается в том, что вы можете использовать
Comparator
этотsort
метод. Java также предоставляет некоторые реализации дляComparator
таких, как, например,Collator
которые полезны для строк сортировки, чувствительных к локали. Вот один пример:Сортировка в параллельных средах
Тем не менее, обратите внимание, что использование
sort
метода не подходит для параллельных сред, поскольку экземпляром коллекции будет манипулировать, и вам следует рассмотреть возможность использования неизменяемых коллекций. Это то, что Guava предоставляет вOrdering
классе, и это простая однострочная строка:3. Оберните ваш список
java.util.PriorityQueue
Хотя в Java нет отсортированного списка, тем не менее есть отсортированная очередь, которая, вероятно, сработает для вас. Это
java.util.PriorityQueue
класс.Нико Хааз в комментариях связался с соответствующим вопросом, который также отвечает на этот вопрос.
В отсортированной коллекции вы, скорее всего, не хотите манипулировать внутренней структурой данных, поэтому PriorityQueue не реализует интерфейс List (потому что это даст вам прямой доступ к его элементам).
Будьте осторожны с
PriorityQueue
итераторомВ
PriorityQueue
классе реализуетIterable<E>
иCollection<E>
интерфейсы , поэтому он может быть итерированным как обычно. Тем не менее, итератор не гарантированно возвращает элементы в отсортированном порядке. Вместо этого (как указывает Альдерат в комментариях), вам нужноpoll()
стоять в очереди, пока она не опустеет.Обратите внимание, что вы можете преобразовать список в приоритетную очередь через конструктор, который принимает любую коллекцию :
4. Напишите свой собственный
SortedList
классПРИМЕЧАНИЕ. Вам не нужно этого делать.
Вы можете написать свой собственный класс List, который сортирует каждый раз, когда вы добавляете новый элемент. Это может привести к значительным вычислительным нагрузкам в зависимости от вашей реализации и будет бессмысленным , если только вы не захотите сделать это в качестве упражнения по двум основным причинам:
List<E>
имеет интерфейс, потому чтоadd
методы должны гарантировать, что элемент будет находиться в индексе, указанном пользователем.Однако, если вы хотите сделать это в качестве упражнения, вот пример кода для начала работы, он использует
AbstractList
абстрактный класс:Обратите внимание, что если вы не переопределили нужные вам методы, то реализации по умолчанию
AbstractList
сгенерируютUnsupportedOperationException
s.источник
Integer maxVal = prioQueue.peek(prioQueue.size() - 1);
. Во-вторых, если вы намереваетесь использовать PriorityQueue просто как отсортированный список,PriorityQueue
в коде будет звучать менее интуитивно, чем если быSortedList
существовала такая структура данных.Collections.sort()
даже позволяет вам определить функцию сравнения, которая используется для сортировки, используяComparator
объект.Потому что концепция списка несовместима с концепцией автоматически отсортированной коллекции. Смысл списка состоит в том, что после вызова
list.add(7, elem)
вызовlist.get(7)
будет возвращенelem
. С автоматически отсортированным списком элемент может оказаться в произвольной позиции.источник
list.get(n)
операция будет детерминированной, то есть она всегда будет возвращать один и тот же элемент в позиции,n
пока список не изменен. Я не согласен с тем, что «концепция списка» требует, чтобы это был порядок вставки. Да,List
интерфейс имеет особенностьlist.add(index, element)
метода, который не имеет смысла для отсортированной коллекции, но это необязательно в соответствии с документами.Поскольку все списки уже «отсортированы» по порядку добавления элементов (упорядочение по FIFO), вы можете «прибегнуть» к ним с другим порядком, включая естественное упорядочение элементов, используя
java.util.Collections.sort()
.РЕДАКТИРОВАТЬ:
Списки как структуры данных основаны на том, что интересует порядок, в котором элементы были вставлены.
Наборы не имеют этой информации.
Если вы хотите заказать, добавив время, используйте
List
. Если вы хотите заказать по другим критериям, используйтеSortedSet
.источник
Set и Map являются нелинейной структурой данных. Список представляет собой линейную структуру данных.
Древовидная структура данных
SortedSet
иSortedMap
интерфейсы реализуютTreeSet
иTreeMap
соответственно используют используемый алгоритм реализации красно-черного дерева . Так что убедитесь, что нет дублирующихся предметов (или ключей в случаеMap
).List
уже поддерживает упорядоченную коллекцию и структуру данных на основе индекса, деревья не являются структурами данных на основе индекса.Tree
по определению не может содержать дубликатов.List
нас могут быть дубликаты, поэтому их нетTreeList
(т.е. нетSortedList
).java.util.Collections.sort()
. Он сортирует указанный список в порядке возрастания в соответствии с естественным порядком его элементов.источник
JavaFX
SortedList
Хотя это заняло некоторое время, в Java 8 есть сортировка
List
. http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.htmlКак вы можете видеть в javadocs, это часть коллекций JavaFX , предназначенная для предоставления отсортированного представления в ObservableList.
Обновление: обратите внимание, что в Java 11 инструментарий JavaFX вышел за пределы JDK и теперь является отдельной библиотекой. JavaFX 11 доступен в виде загружаемого SDK или от MavenCentral. Смотрите https://openjfx.io
источник
Для любого новичка, начиная с апреля 2015 года, Android теперь имеет класс SortedList в библиотеке поддержки, специально разработанный для работы с ним
RecyclerView
. Вот пост в блоге об этом.источник
Другой момент - временная сложность операций вставки. Для вставки списка ожидается сложность O (1). Но это не может быть гарантировано с отсортированным списком.
И самое главное, списки ничего не предполагают об их элементах. Например, вы можете составить списки вещей, которые не реализуются
equals
илиcompare
.источник
SortedSet
из вещей, которые не реализуютComparable
. Смотрите этот конструктор TreeSet .List
интерфейс Java не гарантирует каких-либо спецификаций производительности для его методов.Думайте об этом так:
List
интерфейс имеет такие методы , какadd(int index, E element)
,set(int index, E element)
. Контракт заключается в том, что, как только вы добавили элемент в позиции X, вы найдете его там, если вы не добавите или не удалите элементы перед ним.Если любая реализация списка будет хранить элементы в каком-то порядке, отличном от индекса, вышеприведенные методы списка не будут иметь смысла.
источник
Первая строка в List API говорит, что это упорядоченная коллекция (также известная как последовательность). Если вы сортируете список, вы не можете поддерживать порядок, поэтому в Java нет TreeList.
Как говорит API, Java List вдохновлен Sequence и видит свойства последовательности http://en.wikipedia.org/wiki/Sequence_(matmatics )
Это не значит, что вы не можете отсортировать список, но Java строго его определена и не предоставляет отсортированные версии списков по умолчанию.
источник
В случае, если вы ищете способ сортировки элементов, но также можете эффективно обращаться к ним по индексу, вы можете сделать следующее:
ArrayList
)Затем, чтобы добавить или удалить элемент, вы можете использовать,
Collections.binarySearch
чтобы получить индекс вставки / удаления. Поскольку в вашем списке реализован произвольный доступ, вы можете эффективно изменить список с помощью определенного индекса.Пример:
источник
Рассмотрите возможность использования indexed-tree-map . Это расширенный набор JDK TreeSet, который предоставляет доступ к элементу по индексу и находит индекс элемента без итерации или скрытых базовых списков, которые поддерживают дерево. Алгоритм основан на обновлении весов смены узлов каждый раз, когда происходит изменение.
источник