Una interfaz con método abstracto único único se llama interfaz funcional. Puede utilizar la interfaz funcional predeterminada proporcionada por Java o crear su propia interfaz funcional y utilizarla. Puede comprobar las interfaces funcionales predeterminadas aquí: interfaces funcionales predefinidas todos tienen un solo método abstracto. Es por eso que también se conocen como interfaces de método abstracto único (interfaces SAM).
Para utilizar la expresión lambda en Java, debe crear su propia interfaz funcional o utilizar la interfaz funcional predeterminada proporcionada por Java. A medida que crea su interfaz funcional, márquela con @FunctionalInterface anotación, esta anotación se introdujo en Java 8. Aunque es opcional, debe usarse para obtener un error de compilación si la interfaz marcada con esta anotación no sigue las reglas de interfaz funcional.
¿Cuáles son las reglas para definir una interfaz funcional?
La interfaz funcional debe tener Sólo uno método abstracto. Junto con el método único abstracto, pueden tener cualquier número de métodos predefinidos y estáticos.
Ejemplo 1: creación de su propia interfaz funcional
@FunctionalInterface interface MyFunctionalInterface { public int addMethod(int a, int b); } public class BeginnersBookClass { public static void main(String args[]) { // lambda expression MyFunctionalInterface sum = (a, b) -> a + b; System.out.println("Result: "+sum.addMethod(12, 100)); } }
Producción:
Result: 112
Ejemplo 2: uso de la interfaz funcional predeterminada
import java.util.function.IntBinaryOperator; public class BeginnersBookClass { public static void main(String args[]) { // lambda expression IntBinaryOperator sum = (a, b) -> a + b; System.out.println("Result: " + sum.applyAsInt(12, 100)); } }
Producción:
Result: 112
Ejemplo de interfaz funcional: usar una clase interna anónima versus usar la expresión lambda
Usamos interfaces funcionales incluso antes de java8, se utilizaron creando clases internas anónimas utilizando estas interfaces. Debes haber visto interfaces funcionales como Runnable, ActionListener, Comparator, etc. Todos tienen un único método abstracto. Veamos un ejemplo de ActionListener para ver cómo se usó con la clase interna anónima y cómo se puede implementar usando la expresión lambda.
Ejemplo de ActionListener: antes de Java 8: uso de una clase interna anónima
import javax.swing.*; import java.awt.*; import java.awt.event.*; class Example extends JFrame { JButton button; public Example() { setTitle("Button Action Example without Lambda Expression"); setSize(400,300); setVisible(true); setLayout(new FlowLayout()); setDefaultCloseOperation(EXIT_ON_CLOSE); button = new JButton("Button"); button.setBounds(100,100,90,40); button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ System.out.println("You clicked the button."); } }); add(button); } public static void main(String args[]) { new Example(); } }
Ejemplo de ActionListener: expresión Lambda
import javax.swing.*; import java.awt.*; class Example extends JFrame { JButton button; public Example() { setTitle("Button Action Example using Lambda Expression"); setSize(400,300); setVisible(true); setLayout(new FlowLayout()); setDefaultCloseOperation(EXIT_ON_CLOSE); button = new JButton("Button"); button.setBounds(100,100,90,40); //Lambda expression button.addActionListener(e-> System.out.println("You clicked the button.")); add(button); } public static void main(String args[]) { new Example(); } }