package ar.com.javacuriosities.lambdas; import java.io.File; import java.io.FileFilter; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; /* * Las referencias a métodos nos permite reutilizar un método como una Lambda Expression. * El formato es "target_reference::method_name" */ public class Lesson04MethodAndConstructorReferences { public static void main(String[] args) { /* * Esto es un Lambda complementamente valido pero dado que solo estamos * llamando un método del parámetro podemos usar referencias a métodos */ FileFilter filter = (File f) -> f.canRead(); // Hacemos lo mismo que antes pero con una referencia a método FileFilter enhancedFilter = File::canRead; System.out.println("Filter: " + filter.accept(new File("."))); System.out.println("Enhanced Filter: " + enhancedFilter.accept(new File("."))); /* * Hay 3 tipos de referencias a métodos: * - Métodos estáticos * (args) -> ClassName.staticMethod(args) * ClassName::staticMethod * * - Métodos de instancia de un objeto arbitrario de algún tipo * (arg0, rest) -> arg0.instanceMethod(rest) * ClassName::instanceMethod * * - Métodos de una instancia en particular * (args) -> expr.instanceMethod(args) expr::instanceMethod * * También podemos referirnos a this y dentro de un lambda nos estamos refiriendo * al objeto que contiene el lambda. */ // Static Method Reference Function<Person, String> toJsonFunction = Person::toJson; // Instance method of an arbitrary object of a particular type Function<Person, String> readNameFunction = Person::getName; // Instance method of a particular object Person person = new Person("Cosme Fulanito", 99); PersonValidator validator = new PersonValidator(); Predicate<Person> validateAge = validator::checkAge; System.out.println("******************************"); System.out.println("Json Format: " + toJsonFunction.apply(person)); System.out.println("Name: " + readNameFunction.apply(person)); System.out.println("Validate Age: " + validateAge.test(person)); /* * Además podemos tener referencias a constructores * (args) -> new ClassName(args) * ClassName::new */ BiFunction<String, Integer, Person> personFactory = Person::new; System.out.println(toJsonFunction.apply(personFactory.apply("Pablo Marmol", 404))); } private static final class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } public static String toJson(Person person) { return "{\"Person\":{\"name\":\"" + person.name + "\"}}"; } } private static final class PersonValidator { public boolean checkAge(Person person) { return person.getAge() > 18; } } }