Interlude: Java Lambdas
Setting the scene!¶
Lambdas are anonymous functions. They were added to Java since Java 8 was released. Lambdas can be used in any place a Single Abstract Method was used before.
Let's showcase the use of Lambdas through a demo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @SuppressWarnings("All") public class LambdaDemo { public static void main(String[] args) { } private static List<Course> getSampleCourses() { List<Course> courses = new ArrayList<>(); courses.add(new Course("OOSE", "jhu-oose.com")); courses.add(new Course("Intro OS", "jhu-os.com")); courses.add(new Course("Data Structures", "jhu-ds.com")); return courses; } } |
We start with using anonymous inline classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 | private static void usingAnonymousInlineClass() { List<Course> courses = getSampleCourses(); Collections.sort(courses, new Comparator<Course>() { @Override public int compare(Course c1, Course c2) { return c1.getName().compareTo(c2.getName()); } }); for (Course c: courses) { System.out.println(c); } } |
Call usingAnonymousInlineClass
in main
and it must print out the sample courses sorted by name.
Lambda expression¶
Alright, let's do the same thing with a lambda function!
1 2 3 4 5 6 7 8 9 10 | private static void usingLambdaInLongForm() { List<Course> courses = getSampleCourses(); Collections.sort(courses, (Course c1, Course c2) -> { return c1.getName().compareTo(c2.getName()); }); for (Course c: courses) { System.out.println(c); } } |
The following is syntax sugar for anonymous inline implementation of Comparator
.
1 2 3 | (Course c1, Course c2) -> { return c1.getName().compareTo(c2.getName()); } |
You've used syntax sugar before: the enhanced for loop is syntax sugar for looping through the use of an iterator:
1 2 3 4 5 | Iterator<Course> it = courses.iterator(); while (it.hasNext()) { Course c = it.next(); System.out.println(c); } |
Bak to Lambdas, let's simplify our lambda expression:
1 2 3 4 5 6 | private static void usingLambdaInShortForm() { List<Course> courses = getSampleCourses(); Collections.sort(courses, (c1, c2) -> c1.getName().compareTo(c2.getName())); courses.forEach(course -> System.out.println(course)); } |
- You don't need to specify the data type of arguments.
- When the body of your lambda function is a single statement, you can eliminate the
{
}
and thereturn
keyword.
Also note the use of forEach
method:
1 | courses.forEach(course -> System.out.println(course)); |
We came a long way out of our comfort zone; if this is new to you, your head is probably spinning! But since we came so far, let's throw one more ingredient in the mix: Method References.
Method References¶
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
1 2 3 4 5 | private static void usingMethodReferences() { List<Course> courses = getSampleCourses(); Collections.sort(courses, Comparator.comparing(Course::getName)); courses.forEach(System.out::println); } |