Lambdas and Functional Interfaces
Writing Simple Lambdas
- Functional programming is a way of writing code more declaratively. You specify what you want to do rather than dealing with the state of objects. You focus more on expressions than loops.
- Functional programming uses lambda expressions to write code.
- Lambda expression is an unnamed method.
LAMBDA EXAMPLE
public class Animal {
private String especie;
private boolean podeSaltar;
private boolean podeNadar;
public Animal(String nomeDaEspecie, boolean saltador, boolean nadador){
especie = nomeDaEspecie;
podeSaltar = saltador;
podeNadar = nadador;
}
public boolean podeSaltar() { return podeSaltar; }
public boolean podeNadar() { return podeNadar; }
public String toString() { return especie; }
}
public interface AnalisadorDeAnimal {
boolean teste(Animal a);
}
import java.util.ArrayList;
import java.util.List;
public class TraditionalSearch {
public static void main(String[] args) {
// lista de animais
List<Animal> animais = new ArrayList<Animal>();
animais.add(new Animal("peixe", false, true));
animais.add(new Animal("canguru", true, false));
animais.add(new Animal("coelho", true, false));
animais.add(new Animal("tartaruga", false, true));
// imprime os animais verificados
imprimir(animais, new VerificaSeSaltador());
}
private static void imprimir(List<Animal> animais, Verificador verificador) {
for (Animal animal : animais) {
// verificando
if (verificador.verificar(animal)) {
System.out.print(animal + " ");
}
}
System.out.println();
}
}
canguru coelho
- what if we want to verify if the animal can swin?
- alternative: lambdas
// imprime os animais que podem saltar
imprimir(animais, animal -> animal.podeSaltar());
or
// imprime os animais que podem nadar
imprimir(animais, animal -> animal.podeNadar());
Lambda Syntax
- Lambdas work with interfaces that have only one abstract method.
animal -> animal.podeSaltar()
- syntax:
- a single parameter (animal)
- the arrow to separate the parameter and body;
- a body that calls a single method and returns the result of that method
(Animal animal) -> {return a.podeSaltar();}
- syntax
- A single parameter specified with the name animal and stating the type is Animal
- The arrow operator to separate the parameter and body
- A body that has one or more lines of code, including a semicolon and a return statement
- The parentheses can be omitted only if there is a single parameter;
- Type is not explicitly stated;
- we can omit braces when we have only a single statement.
- Java doesn’t require you to type return or use a semicolon when no braces are used.
Introducing Functional Interfaces
- functional interfaces are interfaces that have only one abstract method;
- you should know the following built-in functional interfaces: Predicate, Consumer, Supplier, and Comparator;
PREDICATE
public interface Predicate<T> {
boolean test(T t);
}
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class UsoDoPredicate {
public static void main(String[] args) {
List<Animal> animais = new ArrayList<>();
animais.add(new Animal("peixe", false, true));
animais.add(new Animal("canguru", true, false));
print(animais, a -> a.podeSaltar());
}
private static void print(List<Animal> animais, Predicate<Animal> verificador) {
for (Animal animal : animais) {
if (verificador.test(animal))
System.out.print(animal + " ");
}
System.out.println();
}
}
canguru
CONSUMER
public interface Consumer<T> {
void accept(T t)
}
import java.util.function.Consumer;
public class UsoDoConsumer {
public static void main(String[] args) {
Consumer<String> consumer = x -> System.out.println(x);
print(consumer, "Hello World");
}
private static void print(Consumer<String> consumer, String value) {
consumer.accept(value);
}
}
Hello World
SUPPLIER
public interface Supplier<T> {
T get();
}
import java.util.function.Supplier;
public class UsoDoSupplier {
public static void main(String[] args) {
Supplier<Integer> number = () -> 42;
System.out.println(returnNumber(number));
}
private static int returnNumber(Supplier<Integer> supplier) {
return supplier.get();
}
}
42
COMPARATOR
- rules, if returns:
- a negative number means the first value is smaller;
- zero means they are equal,
- and a positive number means the first value is bigger.
import java.util.Arrays;
import java.util.Comparator;
public class UsoDoComparator {
public static void main(String[] args) {
Integer [] array = {4, 1, 7, 2, 5};
print(array, (i1, i2) -> i1 - i2);
}
public static void print(Integer [] array, Comparator<Integer> comparator) {
Arrays.sort(array, comparator);
System.out.println(Arrays.toString(array));
}
}
[1, 2, 4, 5, 7]
Working with Variables in Lambdas
- places can appear:
- parameter list;
- local variables declared inside the lambda body;
- variables referenced from the lambda body;
- Method parameters and local variables are allowed to be referenced if they are effectively final (the value of a variable doesn’t change after it is set).
Calling APIs with Lambdas
import java.util.ArrayList;
import java.util.List;
public class ExemploUsandoLambdasEmAPI {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Joao");
names.add("Jose");
names.add("Maria");
System.out.println("Nomes: " + names);
names.removeIf(name -> !name.startsWith("J"));
System.out.println("Nomes iniciando com J: " + names);
names.add("Araci");
names.add("Ze");
System.out.println("\nNomes: " + names);
names.sort((name1, name2) -> name1.compareTo(name2));
System.out.println("Nomes ordenados: " + names);
System.out.println("\nImprimindo novamente");
names.forEach(name -> System.out.println(name));
}
}
Nomes: [Joao, Jose, Maria]
Nomes iniciando com J: [Joao, Jose]
Nomes: [Joao, Jose, Araci, Ze]
Nomes ordenados: [Araci, Joao, Jose, Ze]
Imprimindo novamente
Araci
Joao
Jose
Ze
REMOVEIF()
- takes a Predicate to decide what to remove from the list.
SORT()
- The sort() method takes Comparator that provides the sort order.
FOREACH()
- It takes a Consumer and calls that lambda for each element encountered.
Top comments (0)