JMU
Lambda Expressions
An Introduction with Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
Syntax
Details About the Body
Common Uses
Access
An Example with a Traditional Interface
javaexamples/nested/ComparatorExample.java (Fragment: lambda)
            Arrays.sort(data, (String a, String b) -> 
      {
        if (a == null) a = "";
        if (b == null) b = "";
    
        if      (a.length() > b.length()) return  1;
        else if (a.length() < b.length()) return -1;
        else                              return  0;
      }      
    );
        
An Example with a Nested Interface
The Utility Class and Nested Interface
javaexamples/nested/VectorMath.java
        /**
 * A partial implementation of a utility class for performing vector arithmetic.
 * 
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class VectorMath
{
  /**
   * The requirements of a Metric.
   */
  public interface Metric
  {
    /**
     * Calculate the distance between two vectors.
     * 
     * @param v  One vector
     * @param w  The other vector
     * @return   The distance between v and w
     */
    public abstract double distance(double[] v, double[] w);
  }    
  
  
  /**
   * Find the closest vector in a collection of destinations to the given
   * origin vector.
   * 
   * @param d The Metric to use to calculate the distance
   * @param origin The origin vector
   * @param destinations The set of destination vectors
   * @return A reference to the closes vector in the colelction of destinations
   */
  public static double[] closest(Metric d, double[] origin, double[]... destinations)
  {
    double   min = Double.POSITIVE_INFINITY;
    double[] argmin = null;
    
    for (double[] dest: destinations)
    {
      double temp = d.distance(origin, dest);
      if (temp < min)
      {
        min = temp;
        argmin = dest;
      }
    }
    
    return argmin;
  }
  
}
        
An Example with a Nested Interface (cont.)
Using the Utility Class with One Lambda Expression
javaexamples/nested/VectorMathDriver.java (Fragment: rectilinear)
              double[] nearby = VectorMath.closest(
          // A lambda expression for the rectilinear metric
          (double[] p, double[] q) ->
          {
            double sum = 0.0;
            for (int i=0; i<p.length; i++)
            {
              sum += Math.abs(p[i] - q[i]);
            }
            return sum;
          }, 
          a, b, c);
        
An Example with a Nested Interface (cont.)
Using the Utility Class with Another Lambda Expression
javaexamples/nested/VectorMathDriver.java (Fragment: Euclidean)
              double[] nearby = VectorMath.closest(
          // A lambda expression for the Euclidean metric
          (double[] p, double[] q) ->
          {
            double sum = 0.0;
            for (int i=0; i<p.length; i++)
            {
              sum += Math.pow(p[i] - q[i], 2.0);
            }
            return Math.sqrt(sum);
          }, 
          a, b, c);
        
A JUnit Example
@Test
public void sqrt() {
 Throwable exception = assertThrows(IllegalArgumentException.class, 
   () -> {
           RealMath.sqrt(-1.0);
         });
        assertEquals("The result is not real", exception.getMessage());
}
  
A GUI Example
  JButton close = new JButton("Close");

  // The most complete version
  close.addActionListener(
    (ActionEvent event) -> {f.dispose();}
  );
  
  JButton close = new JButton("Close");

  // Because the method is void it needn't be in a block
  close.addActionListener(
    (ActionEvent event) -> f.dispose() 
  );
  
  JButton close = new JButton("Close");

  // The type of the parameter can be omitted
  close.addActionListener(
    (event) -> f.dispose()
  );
  
  JButton close = new JButton("Close");

  // Because there is one parameter the parentheses can be omitted
  close.addActionListener(
    event -> f.dispose()
  );