Passing Behavior
/**
* LAMBDAS - PASSING BEHAVIOR, NOT OBJECTS
* ---------------------------------------
* Before Java 8, anonymous inner classes were the primary way to
* pass 'behavior' (code) as a parameter.
*
* Lambdas allow us to pass 'behavior' (a block of code) insteed of
* passing an object that wraps that behavior.
*
* A lambdas expression:
* - has no name
* - implements a functional interface
*/
package com.minte9.lambdas.anonymous_inner_classes;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PassingBehavior {
public static void main (String[] args) {
JFrame frame = new JFrame("Inner Class vs Lambda");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
// ---------------------------------------------
// Button 1 - Annonymous Inner Class (old style)
// ---------------------------------------------
JButton buttonInner = new JButton("Inner Class");
buttonInner.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked via INNER CLASS");
}
}
);
// ---------------------------------------------------
// Button 2 - Lambda Expressions (modern style)
// ---------------------------------------------------
JButton buttonLambda = new JButton("Lambda");
buttonLambda.addActionListener(
event -> System.out.println("Clicked via LAMBDA")
);
// ---------------------------------------------------
// Layout
// ---------------------------------------------------
frame.getContentPane().setLayout(new java.awt.FlowLayout());
frame.getContentPane().add(buttonInner);
frame.getContentPane().add(buttonLambda);
frame.setVisible(true);
}
}
Real Example
/**
* ANNONYMOUS INNER CLASS vs LAMBDA - REAL LIFE EXAMPLE
* ----------------------------------------------------
* Scenario:
* We have a list of orders and want to sort them by price.
*
* This example demonstrate:
* 1) Sorting with an anonymous inner class (pre-Java 8)
* 2) Sorting with a lambda expression (Java 8+)
*
* Both approaches pass behavior (comparition logic) to the sort() method.
*/
package com.minte9.lambdas.anonymous_inner_classes;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class RealExample {
public static void main(String[] args) {
List<Order> orders = new ArrayList<>();
orders.add(new Order("Book", 15.99));
orders.add(new Order("Laptop", 1200.));
orders.add(new Order("Pen", 1.50));
// -------------------------------------
// 1) Anonymous Inner Class (pre-Java 8)
// --------------------------------------
orders.sort(
new Comparator<Order>() {
@Override
public int compare(Order o1, Order o2) {
return Double.compare(o1.price(), o2.price());
}
}
);
System.out.println("Sorted with Inner Class:");
orders.forEach(System.out::println);
// -------------------------------------
// 2) Lambda Expressions (Java 8+)
// --------------------------------------
orders.sort(
(o1, o2) -> Double.compare(o1.price(), o2.price())
);
System.out.println("Sorted using lambda:");
orders.forEach(System.out::println);
}
}
record Order(String name, double price) {}
Lambda Definition
/**
* WHAT ARE LAMBDAS?
* -----------------
* A lambda expression is a concise way to represent implementations
* of functional interfaces.
*
* A functional interface is an interface with one abstract method.
*
* Insteed of creating an object with an anonymous inner class,
* lambdas allow us to pass 'behavior' (executable code) directly.
*
* COMMON LAMBDAS FORMS:
* ---------------------
* () -> expresion // no parameters
* () -> { statement } // multiple statements
* (x, y) -> x + y // multiple parameters
*/
package com.minte9.lambdas.anonymous_inner_classes;
import java.util.function.BinaryOperator;
public class LambdaDefinition {
public static void main(String[] args) {
// -----------------------------------
// Lambda with no arguments (Runnable)
// -----------------------------------
Runnable noArgs = () -> System.out.println("Hello World");
new Thread(noArgs).run();
// --------------------------------------
// Lambda with a full block of statements
// --------------------------------------
Runnable multiStatement = () -> {
System.out.println("Hello");
System.out.println("World");
};
new Thread(multiStatement).run();
// ---------------------------------------
// Lambda with parameters (BinaryOperator)
// ---------------------------------------
BinaryOperator<Integer> op = (x, y) -> x + y;
System.out.println(op.apply(2, 3)); // 5
}
}