From charlesreid1

Lambda Expressions

When it comes to dealing with functions as first-class objects in the language, Java is much more limited than Python. In fact, it was not until Java 8 that Java finally got lambda expressions, which are ways of defining functions using in-place, shorthand expressions.

Lambdas for Comparators

You can throw together a fast comparator with a single lambda function, by skipping the class definition and the compare method, and simply using a lambda function instead.

Suppose I have a simple Point object storing two elements:

public class Point {
    public int x, y;
    public Point(int x0, int y0) { this.x = x0; this.y = y0; }
    public String tString() { return "("+this.x+","+this.y+")";}
}

Now suppose we want to sort a list of Point objects, using some kind of custom criteria. We could have Point extend Comparable, and define a compareTo() method, so that we could perform a direct comparison with two point objects. But suppose I have many criteria, and I don't have any control over the Point object source code, so I can't modify the class definition. In this situation I can use a Comparator object, which defines a compare() method taking two objects, performs some calculation, and returns an integer result (analogous to the result that a compareTo method would return).

See Java/Comparable for more on built-in compareTo functionality and extending Comparable.

See Java/Comparators for more on comparators, which we are going to define below with some shorthand.

We will demonstrate with some lambda Comparator examples. here is the framework:

import java.util.Comparator;
import java.util.Arrays;
import java.util.Random;

public class MyComparator {
	public static final Random r = new Random();

	public static void main(String[] args) { 

		// DEFINE COMPARATOR HERE
		
		// Make random points 
		int n = 7;
		Point[] points = new Point[n];
		for(int i=0; i<points.length; i++) { 
			Point p = new Point( randCoord(), randCoord() );
			points[i] = p;
		}
		Arrays.sort(points, pc);
		System.out.println(Arrays.toString(points));
	}

	public static int randCoord() { 
		int MIN = 100;
		int MAX = 999;
		return r.nextInt(MAX-MIN)+MIN;
	}

	public static class Point {
		public int x, y;
		public Point(int x0, int y0) {x=x0; y=y0;}
		public String toString() { return "("+this.x+","+this.y+")"; }
	}

}

Comparator Examples

Compare by x coordinates (if x coordinates are equal, the points are equal):

Comparator<Point> pc = (Point p1, Point p2)->(p2.x-p1.x);

Compare by x coordinates, and break ties by comparing y coordinates:

Comparator<Point> pc = (Point p1, Point p2)->( (p2.x==p1.x)?(p2.y-p1.y)?(p2.x-p1.x) );

Compare points by distance to the origin:

Comparator<Point> pc = (Point p1, Point p2)->(distanceFromOrigin(p2)-distanceFromOrigin(p1)); 

This requires a new method:

	public static int distanceFromOrigin(Point p) { 
		Point o = new Point(0,0);
		return Math.sqrt((p.x-o.x)*(p.x-o.x) + (p.y-o.y)*(p.y-o.y));
	}

References

Oracle Java tutorial on lambda expressions: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html


Flags





See also: