In Java there are the SortedSet
and SortedMap
interfaces. Both belong to Java's standard Collections framework and provide a sorted way to access the elements.
However, in my understanding there is no SortedList
in Java. You can use java.util.Collections.sort()
to sort a list.
Any idea why it is designed like that?
Another point is the time complexity of insert operations. For a list insert, one expects a complexity of O(1). But this could not be guaranteed with a sorted list.
And the most important point is that lists assume nothing about their elements. For example, you can make lists of things that do not implement
equals
orcompare
.List iterators guarantee first and foremost that you get the list's elements in the internal order of the list (aka. insertion order). More specifically it is in the order you've inserted the elements or on how you've manipulated the list. Sorting can be seen as a manipulation of the data structure, and there are several ways to sort the list.
I'll order the ways in the order of usefulness as I personally see it:
1. Consider using
Set
orBag
collections insteadNOTE: I put this option at the top because this is what you normally want to do anyway.
A sorted set automatically sorts the collection at insertion, meaning that it does the sorting while you add elements into the collection. It also means you don't need to manually sort it.
Furthermore if you are sure that you don't need to worry about (or have) duplicate elements then you can use the
TreeSet<T>
instead. It implementsSortedSet
andNavigableSet
interfaces and works as you'd probably expect from a list:If you don't want the natural ordering you can use the constructor parameter that takes a
Comparator<T>
.Alternatively, you can use Multisets (also known as Bags), that is a
Set
that allows duplicate elements, instead and there are third-party implementations of them. Most notably from the Guava libraries there is aTreeMultiset
, that works a lot like theTreeSet
.2. Sort your list with
Collections.sort()
As mentioned above, sorting of
List
s is a manipulation of the data structure. So for situations where you need "one source of truth" that will be sorted in a variety of ways then sorting it manually is the way to go.You can sort your list with the
java.util.Collections.sort()
method. Here is a code sample on how:Using comparators
One clear benefit is that you may use
Comparator
in thesort
method. Java also provides some implementations for theComparator
such as theCollator
which is useful for locale sensitive sorting strings. Here is one example:Sorting in concurrent environments
Do note though that using the
sort
method is not friendly in concurrent environments, since the collection instance will be manipulated, and you should consider using immutable collections instead. This is something Guava provides in theOrdering
class and is a simple one-liner:3. Wrap your list with
java.util.PriorityQueue
Though there is no sorted list in Java there is however a sorted queue which would probably work just as well for you. It is the
java.util.PriorityQueue
class.Nico Haase linked in the comments to a related question that also answers this.
In a sorted collection you most likely don't want to manipulate the internal data structure which is why PriorityQueue doesn't implement the List interface (because that would give you direct access to its elements).
Caveat on the
PriorityQueue
iteratorThe
PriorityQueue
class implements theIterable<E>
andCollection<E>
interfaces so it can be iterated as usual. However, the iterator is not guaranteed to return elements in the sorted order. Instead (as Alderath points out in the comments) you need topoll()
the queue until empty.Note that you can convert a list to a priority queue via the constructor that takes any collection:
4. Write your own
SortedList
classNOTE: You shouldn't have to do this.
You can write your own List class that sorts each time you add a new element. This can get rather computation heavy depending on your implementation and is pointless, unless you want to do it as an exercise, because of two main reasons:
List<E>
interface has because theadd
methods should ensure that the element will reside in the index that the user specifies.However, if you want to do it as an exercise here is a code sample to get you started, it uses the
AbstractList
abstract class:Note that if you haven't overridden the methods you need, then the default implementations from
AbstractList
will throwUnsupportedOperationException
s.Since all lists are already "sorted" by the order the items were added (FIFO ordering), you can "resort" them with another order, including the natural ordering of elements, using
java.util.Collections.sort()
.EDIT:
Lists as data structures are based in what is interesting is the ordering in which the items where inserted.
Sets do not have that information.
If you want to order by adding time, use
List
. If you want to order by other criteria, useSortedSet
.For any newcomers, as of April 2015, Android now has a SortedList class in the support library, designed specifically to work with
RecyclerView
. Here's the blog post about it.First line in the List API says it is an ordered collection (also known as a sequence). If you sort the list you can't maintain the order, so there is no TreeList in Java.
As API says Java List got inspired from Sequence and see the sequence properties http://en.wikipedia.org/wiki/Sequence_(mathematics)
It doesn't mean that you can't sort the list, but Java strict to his definition and doesn't provide sorted versions of lists by default.
Set and Map are non-linear data structure. List is linear data structure.
The tree data structure
SortedSet
andSortedMap
interfaces implementsTreeSet
andTreeMap
respectively using used Red-Black tree implementation algorithm. So it ensure that there are no duplicated items (or keys in case ofMap
).List
is already maintains an ordered collection and index-based data structure, trees are no index-based data structures.Tree
by definition cannot contain duplicates.List
we can have duplicates, so there is noTreeList
(i.e. noSortedList
).java.util.Collections.sort()
. It sorts the specified list into ascending order, according to the natural ordering of its elements.