Implement a Consumer(or any other functional interface), in a class proper to this, in a centralized way, has sometimes its usefulness, as not to spread the same code in several points, mainly when you have statement lambda and not just a simple lambda expression.
Considering their examples, because they’re trivial, they don’t really show us any improvement. Also, in your examples it is not necessary to explain the body as it did - even if it is centralizing the implementation - Ambdas took this verbosity of java, so when you have a functional interface you do not need to explain the signature of the implemented method.
Some examples of advantage in implementing a Consumer
(or any other functional interface) are:
functional interfaces of their own, with one or more methods (just not default, obviously). In these cases you may want to centralize the implementation.
use the Consumer/Supplier/function/etc. to do repetitive things at some points in the code, like this:
public static void main(String[] args) {
final Consumer<Usuario> printName = Usuario::printName;
final Usuario u1 = new Usuario();
u1.name = "Bruno";
final Usuario u2 = new Usuario();
u2.name = "César";
printName.accept(u1);
printName.accept(u2);
}
private static class Usuario {
String name;
void printName() {
System.out.println(name);
}
}
That is, we are applying the same content (again, it can be any functional interface) to several objects, in certain contexts this is interesting.
This is very useful when we have functions that we apply at various points and centralizing, that is, constant functions, something like that:
public interface MathFunctions {
Function<Integer, Integer> funcMultiplicaPor2 = x -> x * 2;
}
public static void main(String[] args) {
System.out.println(MathFunctions.funcMultiplicaPor2.apply(4));
System.out.println(MathFunctions.funcMultiplicaPor2.apply(8));
}
- same functional implementation at several points: imagine that you have a
Consumer
even though the work he does is the same at various points in the code, something like this:
usuarios.forEach(u -> {
u.ativar();
u.setDataHoraAtivacao(LocalDateTime.now());
// mais alguma coisa
});
Instead of spreading it through the code you can have a Consumer
(or, again, any other functional interface) in Usuario
and only refer to it:
final Consumer<Usuario> ATIVACAO_CONSUMER = u -> {
u.ativar();
u.setDataHoraAtivacao(LocalDateTime.now());
// mais alguma coisa
};
usuarios.forEach(Usuario.ATIVACAO_CONSUMER);
This sort of thing is useful when we have Function
that we referenced in various parts, as cases we have a function to map a generic type T to another type, for example. Another case is when we have a Comparator
not the implemented standard, something like that:
public static final Comparator<Usuario> USUARIO_COMPARATOR = Comparator.comparing(Usuario::getNome).thenComparing(Usuario::getCPF);
To use like this:
final Set<Usuario> usuarios = usuarios.stream().sorted(Usuario.USUARIO_COMPARATOR).collect(Collections.toSet());
Note: realize that this is an example, in this case it may be better a method that does the activation things ;)
In short: it will depend a lot on what you are using, usually only affects code organization, personal practices, etc., otherwise you do not need to explicitly implement such interfaces. In large applications you can decide to have a design only of functional interfaces (such as predicates and operators) that are shared by the application, utilitarian things and such.
Another point I saw, that maybe you are not used to (even if you used it above), in this example:
usuarios.forEach(u -> System.out.println(u));
You don’t need to use a lambda expression, you can use method Reference:
usuarios.forEach(System.out::println);
In this case you are referencing a static method that takes as argument the parameter of the type of the Consumer
informed, inferred by the collection.
Hello, Edson. Welcome to [en.so]! Actually your question is about the use of Windows and not about the interface
Consumer
. The two codes are equivalent and the ambles are just a simpler way to avoid all that code to implement the interface, what we call.– utluiz
Thanks for the feedback, it’s really much simpler and it covers many lines of code, but is there any scenario where we need to use Consummer ? Or not ?
– HashMap