5

Do we have sorted list in java just like SortedSet or TreeMap ? I have a class having one of the property as List of objects. This list has to be sorted at any time when adding or when setting it through setters (set(List list)).

Do we have any component like TreeMap for list ? Any suggestions or help will be really appreciable. Thanks in advance.

Lolly
  • 34,250
  • 42
  • 115
  • 150
  • Why do you need it to be a list? If it has to be a list you can use binary search insert or call Collection.sort() each timer. No collection will re-sort you change an element in the collection. – Peter Lawrey Nov 05 '12 at 16:29

5 Answers5

7

The purpose of having a list is that they should maintain the order of the elements in which they were added. So, I believe there is no such List implementation in which the elements are sorted as they are added.

You can use Collections.sort() method to sort the list any time.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
  • 1
    +1 Exactly - what's the point of methods like `add(int index, E element)` if the element isn't going to end up there? It's just not the right interface. – Paul Bellora Nov 05 '12 at 16:46
  • There are perfectly valid reasons to want to have a continually sorted list (since SortedSet does not allow duplicates). add(int, E) etc of course need to throw UnsupportedOperationException - hardly unusual or outrageous behaviour in the world of java Collections. – barneypitt Aug 13 '22 at 09:30
2

What you want is a sorted Bag/MultiSet implementation, like Google Guava's TreeMultiSet ?

A TreeMultiSet in Guava is defined as:

A multiset which maintains the ordering of its elements, according to either their natural order or an explicit Comparator.

Where a MultiSet is:

A collection that supports order-independent equality, like Set, but may have duplicate elements. A multiset is also sometimes called a bag.

For more information about MultiSets, you can read this dzone article on Google Guava: MultiSets (except in your case you really want the TreeMultiSet), and this page of the Guava wiki explaining their new collection types.

haylem
  • 22,460
  • 3
  • 67
  • 96
  • A `MultiSet` is quite different from a `List` though. – Paul Bellora Nov 05 '12 at 16:43
  • @PaulBellora: yes, in that it should only have unique elements if you consider it a real set, which it isn't. From the OP's question, that's really exactly what he's after. – haylem Nov 05 '12 at 16:46
  • @PaulBellora: I assume it could be annoying if the OP's API relied on a `List` interface. But the MultiSet implements the `Collection` interface, so that seems like a problem that could be relatively easily fixed. – haylem Nov 05 '12 at 16:47
  • The `MultiSet.iterator` documentation doesn't say anything about insertion order. Other methods like `entrySet` have unspecified order. It's hard to see how this interface matches up with `List`. – Paul Bellora Nov 05 '12 at 16:53
  • @PaulBellora: Try it, and you'll see. Also, the OP didn't say anything about insertion order, but about wanting a list-like data structure that can be kept sorted. The `MultiSet.iterator()` simply guarantees you'll get back item in the order that's defined by the underlying comparator. Also, as you mentioned yourself in a comment to another answer, `List` doesn't seem to be the right interface anyway for this purpose, so it does make sense that this wouldn't "match up with `List`": it doesn't look like he really wants a `List`. – haylem Nov 05 '12 at 16:58
  • Okay I think we're on the same page. Sorry for annoying you. – Paul Bellora Nov 05 '12 at 17:01
  • @PaulBellora: don't mind at all, my answer obviously wasn't clear at first. – haylem Nov 05 '12 at 17:03
  • `TreeMultiset` retains sorted order... – Louis Wasserman Nov 05 '12 at 17:30
  • @LouisWasserman: Yes, I think that's pretty clear from the doc of the class, but I think Paul meant to say that the particular Javadoc entry for `iterator()` could lead to confusion. (Thanks for all your amazing work on Guava, btw. Looking forward to each release every time.) – haylem Nov 05 '12 at 17:40
0

You may use some other data type for your Collection since you do not care about the order of elements (which is an essential property of a List). For example I think that SortedSet can do the trick if you don't have duplicates.

Otherwise you can use Collections.sort() on your List.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
0

You can extends existing ArrayList To create a SortedList. As you will only have to take care of order while insertion.

public class SortedList<E extends Comparable<E>> extends ArrayList<E> {

    @Override
    public boolean add(E e) {
        int index = Collections.binarySearch(this, e);
        super.add(index < 0 ? ~index : index, e);
        return true;
    };
}

Java Doc Collections.binarySearch

Returns: the index of the search key, if it is contained in the list; otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size() if all elements in the list are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found.

Update: As @Louis Wasserman has pointed out this create problems with basic list contract that is insert elements based on index. If you want to support that functionality then you should use Collections.sort(). You can also use org.apache.commons.collections.list.TreeList which has below relative performance statistics to that class

              get  add  insert  iterate  remove
TreeList       3    5       1       2       1
ArrayList      1    1      40       1      40
LinkedList  5800    1     350       2     325
Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72
  • 1
    You realize that violates the `List` contract and would get all sorts of code messed up, right? – Louis Wasserman Nov 05 '12 at 17:21
  • Rather than throwing out the whole idea, and using Collections.sort, consider adding insertInOrder as an additional method to SortedList. The methods that are specified in List would do what the List contract says. – Patricia Shanahan Nov 05 '12 at 19:49
-1

The Java SDK doesn't have a sorted List class. The easiest solution for what you need would be to call Collections.sort() on your List every time you add something to it.

mluisbrown
  • 14,448
  • 7
  • 58
  • 86