Java 8: Sorting Values in Collections
Join the DZone community and get the full member experience.
Join For FreeHaving realised that Java 8 is due for its GA release within the next few weeks I thought it was about time I had a look at it and over the last week have been reading Venkat Subramaniam’s book.
I’m up to chapter 3 which covers sorting a collection of people. The Person class is defined roughly like so:
static class Person { private String name; private int age; Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return String.format("Person{name='%s', age=%d}", name, age); } }
In the first example we take a list of people and then sort them in ascending age order:
List<Person> people = Arrays.asList(new Person("Paul", 24), new Person("Mark", 30), new Person("Will", 28)); people.stream().sorted((p1, p2) -> p1.age - p2.age).forEach(System.out::println);
Person{name='Paul', age=24} Person{name='Will', age=28} Person{name='Mark', age=30}
If we were to write a function to do the same thing in Java 7 it’d look like this:
Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.age - o2.age; } }); for (Person person : people) { System.out.println(person); }
Java 8 has reduced the amount of code we have to write although it’s still more complicated than what we could do in Ruby:
> people = [ {:name => "Paul", :age => 24}, {:name => "Mark", :age => 30}, {:name => "Will", :age => 28}] > people.sort_by { |p| p[:age] } => [{:name=>"Paul", :age=>24}, {:name=>"Will", :age=>28}, {:name=>"Mark", :age=>30}]
A few pages later Venkat shows how you can get close to this by using the Comparator#comparing function:
Function<Person, Integer> byAge = p -> p.age ; people.stream().sorted(comparing(byAge)).forEach(System.out::println);
I thought I could make this simpler by inlining the ‘byAge’ lambda like this:
people.stream().sorted(comparing(p -> p.age)).forEach(System.out::println);
This seems to compile and run correctly although IntelliJ 13.0 suggests there is a ‘cyclic inference‘ problem. IntelliJ is happy if we explicitly cast the lambda like this:
people.stream().sorted(comparing((Function<Person, Integer>) p -> p.age)).forEach(System.out::println);
IntelliJ also seems happy if we explicitly type ‘p’ in the lambda, so I think I’ll go with that for the moment:
people.stream().sorted(comparing((Person p) -> p.age)).forEach(System.out::println);
Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Implementing a Serverless DevOps Pipeline With AWS Lambda and CodePipeline
-
How To Use Pandas and Matplotlib To Perform EDA In Python
-
What Is JHipster?
-
4 Expert Tips for High Availability and Disaster Recovery of Your Cloud Deployment
Comments