lunes, 27 de junio de 2016

Interfaces Funcionales en Java


La programación funcional tiene un apogeo desde hace tiempo y todos los lenguajes se ven afectado por este éxito, por supuesto Java no es la excepción.

Las interfaces funcionales no son diferentes de la interfaz común.  Ahora con Java 8, podemos tener métodos por defecto en las interfaces con la palabra clave default,  por lo tanto puede haber cualquier número de métodos por defecto en una interfaz; sin embargo, si tiene un sólo una método abstracto se puede considerar como una interfaz funcional. Y podemos utilizar la anotación @FunctionalInterface que si bien es opcional, nos viene bien para documentar.

Por ejemplo:

@FunctionalInterface
public interface MyFuncInterface1{
    public abstract void functionalMethod1();
}

@FunctionalInterface
public interface MyFuncInterface2{
    public abstract void functionalMethod2();
    public default boolean isPresent(){
      return true;
   }
}

Las interfaces funcionales son interfaces con sólo un método abstracto, se deduce inmediatamente que el énfasis se encuentra en lo que hace, es decir es una interfaz que encapsula un comportamiento. Un ejemplo es Runnable :

class RunnableImpl implements Runnable{

   public void run (){
      //do something in a new thread
    }
}

Ahora podemos pasar una instancia de esta clase a un hilo, es más podemos utilizar una clase abstracta:

new Thread(new Runnable(){
   public void run(){
     //do something in this thread
  }
},"NEW-THREAD").start();

Como se puede ver hemos escrito mucho código, solo para pasar una función por parámetro. Por que no usar una expresión Lambda:

new Thread(()->{
   //do something in this thread
}, "NEW-THREAD").start();

Que paso? La interfaz se elimino? En efecto, pudimos pasar sólo la función, el nuevo hilo correría el bloque de código (dentro del método run)

Java 8 proporciona un conjunto completo de interfaces funcionales dentro del paquete java.util.function. Estas interfaces funcionales se adaptan a la mayoría de los requisitos generales de desarrollo diario.

Veamos algún ejemplo:

IntStream intStream = IntStream.of(1,2,3,4,5);
intStream.filter(new IntPredicate() {

           @Override
           public boolean test(int value) {
               if(value%2 != 0)
                   return false;
               return true;
           }
     });

Podemos cambiarlo por:

IntStream intStream = IntStream.of(1,2,3,4,5);
intStream.filter(val -> {
            if (val % 2 != 0)
                return false;
            return true;
               
 });

Interfaces funcionales son un medio de hacer funciones de primer orden, llevando el mundo funcional al orientado a objetos.