Could somebody show me a quick example how to sort an ArrayList
alphabetically in Java 8 using the new lambda syntax.
-
2I suggest you to read this: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html – Alexis C. May 16 '14 at 18:10
12 Answers
For strings this would work
arrayList.sort((p1, p2) -> p1.compareTo(p2));

- 816
- 6
- 6
-
39
-
25Even better: [`arrayList.sort(Comparator.naturalOrder())`](http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder--) – Holger May 19 '14 at 09:08
-
32Note that both `.sort(String::compareTo) and .sort(Comparator.naturalOrder())` will sort **all** upper case letters before any lower case letters. Usually what you want is `.sort(String::compareToIgnoreCase)` – UTF_or_Death Apr 13 '16 at 16:58
Are you just sorting String
s? If so, you don't need lambdas; there's no point. You just do
import static java.util.Comparator.*;
list.sort(naturalOrder());
...though if you're sorting objects with a String
field, then it makes somewhat more sense:
list.sort(comparing(Foo::getString));

- 91,686
- 21
- 171
- 177

- 191,574
- 25
- 345
- 413
Use list.sort(String::compareToIgnoreCase)
Using list.sort(String::compareTo)
or list.sort(Comparator.naturalOrder())
will give incorrect (ie. non-alphabetical) results. It will sort any upper case letter before all lower case letters, so the array ["aAAA","Zzz", "zzz"]
gets sorted to ["Zzz", "aAAA", "zzz"]

- 864
- 11
- 19
Suppose you have List of names(String) which you want to sort alphabetically.
List<String> result = names.stream().sorted(
Comparator.comparing(n->n.toString())).collect(Collectors.toList());
its working perfectly.

- 11,842
- 9
- 51
- 66
In functional programming, you're not using the old objects to operate on them, but creating the new one in such a fashion:
list.stream().sorted().map(blah-blah).filter(...)...

- 7,391
- 2
- 37
- 48
-
This is incorrect, as now the stream no longer consists of the old elements, but of the mapped and filtered version. Consider a bank account which you want to sort by person name: If you do it like you suggest, then you start of with a stream of bank accounts, and end up with a stream of person names, while you want to end up with a stream of bank accounts again. – skiwi May 17 '14 at 10:04
-
Generally, when you write your programs in FP-style, you don't need to iterately save the results. So, this all is a **new** list(s): list.stream().sorted() is not sorting the old list, but creating the new one. – Dmitry Ginzburg May 17 '14 at 10:09
-
And that list has just became useless as you **only** have the person's name left (in my example), and you cannot reference it back (directly) to their bank account anymore. – skiwi May 17 '14 at 10:11
-
Also, possibly a source of your confusion (nothing to blame), is that the OP requested a method to sort a list, yet you only return an intermediary stream, you also will need to store it at some point, which you omitted from your answer. By trying to implement that, you may see the issue yourself aswell. – skiwi May 17 '14 at 10:12
-
If you **really** want to store the result in the same list, you can do something like: `list = list.stream().sort().collect(Collectors.toList());`, but again, author was requesting something in Java 8 style, and that's in Java 8 style. – Dmitry Ginzburg May 17 '14 at 10:17
-
You have now omitted specifying the sort-operator, please first get a working example, then update your answer with the working example. – skiwi May 17 '14 at 10:18
-
1@skiwi there's no need to specify the sort operator as OP wanted to sort `String`s in lexicographic order, it's the default behavior. – Dmitry Ginzburg May 17 '14 at 10:19
Lambdas shouldn't be the goal. In your case, you can sort it the same way as in Java 1.2:
Collections.sort(list); // case sensitive
Collections.sort(list, String.CASE_INSENSITIVE_ORDER); // case insensitive
If you want to do it in Java 8 way:
list.sort(Comparator.naturalOrder()); // case sensitive
list.sort(String.CASE_INSENSITIVE_ORDER); // case insensitive
You can also use list.sort(null)
but I don't recommend this because it's not type-safe.

- 36,558
- 20
- 126
- 155
A really generic solution would be to introduce some StreamUtil
like
public class StreamUtil {
private StreamUtil() {
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <TYPE> Comparator<TYPE> sort(Function<TYPE, ? extends Comparable> getterFunction, boolean descending) {
if (descending) {
return (o1, o2) -> getterFunction.apply(o2).compareTo(getterFunction.apply(o1));
}
return (o1, o2) -> getterFunction.apply(o1).compareTo(getterFunction.apply(o2));
}
}
The call would look something like
list.stream().sorted(sort(YourClass::getSortProperty, true));

- 3,794
- 9
- 46
- 80
If you have an array with elements that have natural ordering (i.e String
, int
, double
); then it can be achieved by:
List<String> myList = new ArrayList<>();
myList.add("A");
myList.add("D");
myList.add("C");
myList.add("B");
myList.sort(Comparator.comparing(s -> s));
myList.forEach(System.out::println);
If on the another hand you have an array of objects and you want to sort base on some sort of object field, then you can use:
class User {
double score;
// Constructor // Getters // Setters
}
List<User> users = new ArrayList<>();
users.add(new User(19d));
users.add(new User(67d));
users.add(new User(50d));
users.add(new User(91d));
List<User> sortedUsers = users
.stream()
.sorted(Comparator.comparing(User::getScore))
.collect(Collectors.toList());
sortedUsers.forEach(System.out::println);
If the sorting is more complex, then you would have to write your own comparator and pass that in.

- 4,865
- 4
- 39
- 40
List<Product> list = new ArrayList<>();
List<String> list1 = new ArrayList<>();
list.add(new Product(1));
list.add(new Product(2));
list.add(new Product(3));
list.add(new Product(10));
Collections.sort(list, Comparator.comparing((Product p) -> p.id));
for (Product p : list) {
System.out.println(p.id);
}

- 11
- 1
-
Sticking to functional programming, for (Product p : list) { System.out.println(p.id); } can be written as list.stream().forEach(System.out::println); – Shahzad Oct 18 '20 at 15:04
The syntax including a custom comparator is quite simple, and quick, for example here the ArrayList being sorted contains JSONObjects, and I will sort it based on a property called 'order':
arrayList.sort((JSONObject o1, JSONObject o2)->o1.getInt("order")-o2.getInt("order"));
I think this is a really nice and concise syntax, easy to read and less bulky than non-lambda syntax.

- 43
- 5
To sort ArrayList of String in n descending order just refer to this type And if You are looking for ascending then replace a1 with a2.
Collections.sort(ArrayListName,(a1,a2)->a2.compareTo(a1));