Why not try TreeSet. Does your list not allow duplicates? If so then the Set should be ok. As you are adding strings and this implements Comparator the set will be automatically sorted for you
If you had
Set<String> s = new TreeSet<String>();
s.add("B");
s.add("C");
s.add("A");
then the contents of the set would be A, B, C
Answer from RNJ on Stack OverflowWhy not try TreeSet. Does your list not allow duplicates? If so then the Set should be ok. As you are adding strings and this implements Comparator the set will be automatically sorted for you
If you had
Set<String> s = new TreeSet<String>();
s.add("B");
s.add("C");
s.add("A");
then the contents of the set would be A, B, C
You can use TreeMap
A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
java - How can I sort a List alphabetically? - Stack Overflow
How to sort a list alphabetically and place any items that begin with a number at the bottom
java - How to sort a HashSet? - Stack Overflow
Custom Alphabetic Sorting of Array in Java - Software Engineering Stack Exchange
Assuming that those are Strings, use the convenient static method sort:
Collections.sort(listOfCountryNames)
Solution with Collections.sort
If you are forced to use this List, or if your program has a structure like
- Create a list
- Add some country names
- sort them once
- never change that list again
then Thilos answer is the best way to do it. Combine it with the advice from Tom Hawtin - tackline and you get
java.util.Collections.sort(listOfCountryNames, Collator.getInstance());
Solution with a TreeSet
If you have the choice, and if your application is likely to become more complex, you could modify your code to use a TreeSet instead. This kind of collection sorts your items as they are inserted. There is no need to call sort().
Collection<String> countryNames =
new TreeSet<String>(Collator.getInstance());
countryNames.add("UK");
countryNames.add("Germany");
countryNames.add("Australia");
// Voila... sorted.
Side note on why I prefer the TreeSet
It has some subtle but important advantages:
- It's just shorter. But only one line shorter.
- Never worry about is this list really sorted right now, because a TreeSet is always sorted, no matter what you do.
- You cannot have duplicate entries. Depending on your situation, this can be a pro or a con. If you need duplicates, stick to your list.
- An experienced programmer looks at
TreeSet<String> countyNamesand immediately knows: this is a sorted collection of strings without duplicates, and I can be sure that this is true at any moment. So much information in one short declaration. - A real performance gain in some cases. If you use a list, and you insert values very often, and the list may be read between those insertions, then you have to sort the list after each insertion. The set does the same thing, but much faster.
Using the right collection for the right task is a key to writing short and bug-free code. It's not so demonstrative in this case, because you're only saving one line. But I've lost count of how often I see someone using a list when they want to make sure there are no duplicates, and then building that functionality themselves. Or even worse, using two lists when you really need one map.
Don't get me wrong: Using Collections.sort is not a bug or a mistake. But there are many cases where the TreeSet is much cleaner.
Given a list, in my example it's an array list, I need to sort it alphabetically (case insensitive). The values in my list either begin with a letter, or a number. The numbers are supposed to be placed at the bottom of the sorted list.
This is a one-line task, except for the last part.
You can easily do it with:
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
The problem with this is that it places items beginning with a number at the top of the list.
What I want is:
["Alpha", "Bravo", "Delta", "1", "2"]
What I get is:
["1", "2", "Alpha", "Bravo", "Delta"]
What's the proper way to do this? I could always chop the list and append the number items to the bottom, but that seems wrong.
A HashSet does not guarantee any order of its elements. If you need this guarantee, consider using a TreeSet to hold your elements.
However if you just need your elements sorted for this one occurrence, then just temporarily create a List and sort that:
Set<?> yourHashSet = new HashSet<>();
...
List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);
Add all your objects to the TreeSet, you will get a sorted Set. Below is a raw example.
HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);
TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]
Update
You can also use TreeSet's constructor that takes a HashSet as a parameter.
HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);
TreeSet myTreeSet = new TreeSet(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]
Thanks @mounika for the update.
Java 8
Set<Integer> myHashSet = new HashSet<>();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);
LinkedHashSet<Integer> ascendingSortedSet = myHashSet.stream()
.sorted()
.collect(Collectors.toCollection(LinkedHashSet::new)); // Prints [1, 12, 23, 45]
LinkedHashSet<Integer> descendingSortedSet = myHashSet.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toCollection(LinkedHashSet::new)); // Prints [45, 23, 12, 1]