Umesh Awasthi
Umesh Awasthi

Reputation: 23587

Sorting Values of Set

I am trying to sort elements of a set but unable to do so far. here is my code which i am trying to do

public static void main(String [] args){
    Set<String> set=new HashSet<String>();
    set.add("12");
    set.add("15");
    set.add("5");
    List<String> list=asSortedList(set);
}

public static
<T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
  List<T> list = new ArrayList<T>(c);
  Collections.sort(list);
  return list;
}

but this or other way is not working since its all time giving me the same order in which they have been filled 12,15,5

Upvotes: 41

Views: 157306

Answers (6)

Matt Ball
Matt Ball

Reputation: 359786

You're using the default comparator to sort a Set<String>. In this case, that means lexicographic order. Lexicographically, "12" comes before "15", comes before "5".

Either use a Set<Integer>:

Set<Integer> set=new HashSet<Integer>();
set.add(12);
set.add(15);
set.add(5);

Or use a different comparator:

Collections.sort(list, new Comparator<String>() {
    public int compare(String a, String b) {
        return Integer.parseInt(a) - Integer.parseInt(b);
    }
});

Upvotes: 8

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298838

Use a SortedSet (TreeSet is the default one):

SortedSet<String> set=new TreeSet<String>();
set.add("12");
set.add("15");
set.add("5");
List<String> list=new ArrayList<String>(set);

No extra sorting code needed.

Oh, I see you want a different sort order. Supply a Comparator to the TreeSet:

new TreeSet<String>(Comparator.comparing(Integer::valueOf));

Now your TreeSet will sort Strings in numeric order (which implies that it will throw exceptions if you supply non-numeric strings)

Reference:

Upvotes: 70

mikej
mikej

Reputation: 66263

If you sort the strings "12", "15" and "5" then "5" comes last because "5" > "1". i.e. the natural ordering of Strings doesn't work the way you expect.

If you want to store strings in your list but sort them numerically then you will need to use a comparator that handles this. e.g.

Collections.sort(list, new Comparator<String>() {
    public int compare(String o1, String o2) {
        Integer i1 = Integer.parseInt(o1);
        Integer i2 = Integer.parseInt(o2);
        return (i1 > i2 ? -1 : (i1 == i2 ? 0 : 1));
    }
});

Also, I think you are getting slightly mixed up between Collection types. A HashSet and a HashMap are different things.

Upvotes: 31

dimitrisli
dimitrisli

Reputation: 21381

Use the Integer wrapper class instead of String because it is doing the hard work for you by implementing Comparable<Integer>. Then java.util.Collections.sort(list); would do the trick.

Upvotes: 4

Faisal Feroz
Faisal Feroz

Reputation: 12785

You need to pass in a Comparator instance to the sort method otherwise the elements will be sorted in their natural order.

For more information check Collections.sort(List, Comparator)

Upvotes: 0

Jonathon Faust
Jonathon Faust

Reputation: 12545

Strings are sorted lexicographically. The behavior you're seeing is correct.

Define your own comparator to sort the strings however you prefer.

It would also work the way you're expecting (5 as the first element) if you changed your collections to Integer instead of using String.

Upvotes: 1

Related Questions