logo

Interfaces funcionales en Java

Java siempre ha sido un lenguaje de programación orientado a objetos. Por lenguaje de programación orientado a objetos, podemos declarar que todo lo presente en el lenguaje de programación Java rota a través de los Objetos, excepto algunos de los tipos de datos primitivos y métodos primitivos por integridad y simplicidad. No existen funciones exclusivas presentes en un lenguaje de programación llamado Java. Las funciones en el lenguaje de programación Java son parte de una clase, y si alguien quiere usarlas, debe usar la clase u objeto de la clase para llamar a cualquier función.

Interfaces funcionales de Java

A interfaz funcional es una interfaz que contiene solo un método abstracto. Sólo podrán tener una funcionalidad a exhibir. Desde Java 8 en adelante, expresiones lambda se puede utilizar para representar la instancia de una interfaz funcional. Una interfaz funcional puede tener cualquier número de métodos predeterminados. Ejecutable , Oyente de acción , y Comparable son algunos de los ejemplos de interfaces funcionales.



La interfaz funcional también se reconoce como Interfaces de método abstracto único . En resumen, también se les conoce como interfaces SAM . Las interfaces funcionales en Java son la nueva característica que proporciona a los usuarios el enfoque de la programación fundamental.

Se incluyen interfaces funcionales en Java SE 8 con expresiones Lambda y referencias de métodos para hacer que el código sea más legible, limpio y sencillo. Las interfaces funcionales son interfaces que garantizan que incluyan precisamente un solo método abstracto. Las interfaces funcionales se utilizan y ejecutan representando la interfaz con un anotación llamada @Interfaz funcional . Como se describió anteriormente, las interfaces funcionales pueden contener solo un método abstracto. Sin embargo, pueden incluir cualquier cantidad de métodos estáticos y predeterminados.

En las interfaces funcionales, no es necesario utilizar la palabra clave abstracta, ya que es opcional utilizarla porque, de forma predeterminada, el método definido dentro de la interfaz es solo abstracto. También podemos llamar expresiones Lambda como instancia de interfaz funcional.



Ejemplo de interfaces funcionales de Java

Ejemplo 1:

Antes de Java 8, teníamos que crear objetos de clase internos anónimos o implementar estas interfaces.

Java






// Java program to demonstrate functional interface> class> Test {> >public> static> void> main(String args[])> >{> >// create anonymous inner class object> >new> Thread(>new> Runnable() {> >@Override> public> void> run()> >{> >System.out.println(>'New thread created'>);> >}> >}).start();> >}> }>

>

>

Producción

New thread created>

Ejemplo 2:

Java 8 en adelante, podemos asignar expresión lambda a su objeto de interfaz funcional como este:

Java




// Java program to demonstrate Implementation of> // functional interface using lambda expressions> class> Test {> >public> static> void> main(String args[])> >{> >// lambda expression to create the object> >new> Thread(() ->{> >System.out.println(>'New thread created'>);> >}).start();> >}> }>

explicar la independencia de los datos

>

>

Producción

New thread created>

Anotación @FunctionalInterface

La anotación @FunctionalInterface se utiliza para garantizar que la interfaz funcional no pueda tener más de un método abstracto. En caso de que esté presente más de un método abstracto, el compilador marca un mensaje de 'Anotación @FunctionalInterface inesperada'. Sin embargo, no es obligatorio utilizar esta anotación.

A continuación se muestra la implementación del tema anterior:

Java

alinear imágenes en css




// Java program to demonstrate lambda expressions to> // implement a user defined functional interface.> @FunctionalInterface> interface> Square {> >int> calculate(>int> x);> }> class> Test {> >public> static> void> main(String args[])> >{> >int> a =>5>;> >// lambda expression to define the calculate method> >Square s = (>int> x) ->x*x;> >// parameter passed and return type must be> >// same as defined in the prototype> >int> ans = s.calculate(a);> >System.out.println(ans);> >}> }>

>

>

Producción

25>

Algunas interfaces funcionales Java integradas

Desde Java SE 1.8 en adelante, existen muchas interfaces que se convierten en interfaces funcionales. Todas estas interfaces están anotadas con @FunctionalInterface. Estas interfaces son las siguientes:

    Ejecutable -> Esta interfaz solo contiene el método run(). Comparable -> Esta interfaz solo contiene el método compareTo(). ActionListener -> Esta interfaz solo contiene el método actionPerformed(). Invocable -> Esta interfaz solo contiene el método call().

Java SE 8 incluía cuatro tipos principales de interfaces funcionales que se puede aplicar en múltiples situaciones como se menciona a continuación:

    Proveedor de función de predicado del consumidor

Entre las cuatro interfaces anteriores, las tres primeras interfaces, es decir, Consumidor, Predicado y Función, también tienen adiciones que se proporcionan a continuación:

  1. Consumidor -> Bi-Consumidor
  2. Predicado -> Bipredicado
  3. Función -> Bifunción, Operador unario, Operador binario

1. Consumidor

La interfaz de consumidor de la interfaz funcional es la que acepta solo un argumento o un argumento aburguesado. La interfaz del consumidor no tiene valor de retorno. No devuelve nada. También existen variantes funcionales del Consumidor: DoubleConsumer, IntConsumer y LongConsumer. Estas variantes aceptan valores primitivos como argumentos.

Además de estas variantes, también existe una variante más de la interfaz del Consumidor conocida como Bi-Consumer.

Bi-consumidor – Bi-Consumer es la variante más interesante de la interfaz del consumidor. La interfaz del consumidor toma solo un argumento, pero por otro lado, la interfaz Bi-Consumer toma dos argumentos. Tanto el Consumidor como el Bi-Consumidor no tienen valor de retorno. Tampoco devuelve nada parecido a la interfaz del consumidor. Se utiliza para iterar a través de las entradas del mapa.

Sintaxis / Prototipo de interfaz funcional del consumidor –

Consumer consumer = (value) ->System.out.println(valor);>

Esta implementación de la interfaz funcional del consumidor de Java imprime el valor pasado como parámetro a la declaración de impresión. Esta implementación utiliza la función Lambda de Java.

2. Predicado

En lógica científica, una función que acepta un argumento y, a cambio, genera un valor booleano como respuesta se conoce como predicado. De manera similar, en el lenguaje de programación Java, una interfaz funcional predicada de Java es un tipo de función que acepta un único valor o argumento y realiza algún tipo de procesamiento sobre él, y devuelve una respuesta booleana (Verdadero/Falso). La implementación de la interfaz funcional Predicate también encapsula la lógica del filtrado (un proceso que se utiliza para filtrar componentes de flujo en base a un predicado proporcionado) en Java.

Al igual que la interfaz funcional del Consumidor, la interfaz funcional Predicado también tiene algunas extensiones. Estos son IntPredicate, DoublePredicate y LongPredicate. Estos tipos de interfaces funcionales de predicados aceptan solo valores o tipos de datos primitivos como argumentos.

Bipredicado – Bi-Predicate también es una extensión de la interfaz funcional Predicate, que, en lugar de uno, toma dos argumentos, realiza algún procesamiento y devuelve el valor booleano.

Sintaxis de la interfaz funcional de predicado –

public interface Predicate { boolean test(T t); }>

La interfaz funcional predicada también se puede implementar mediante una clase. La sintaxis para la implementación de una interfaz funcional predicada utilizando una clase se proporciona a continuación:

public class CheckForNull implements Predicate { @Override public boolean test(Object o) { return o != null; } }>

La interfaz funcional de predicado de Java también se puede implementar mediante expresiones Lambda. A continuación se proporciona un ejemplo de la implementación de la interfaz funcional Predicate:

Predicate predicate = (value) ->valor != nulo;>

Esta implementación de interfaces funcionales en Java usando expresiones Java Lambda es más manejable y efectiva que la implementada usando una clase, ya que ambas implementaciones hacen el mismo trabajo, es decir, devuelven el mismo resultado.

3. Función

Una función es un tipo de interfaz funcional en Java que recibe un solo argumento y devuelve un valor después del procesamiento requerido. Hay muchas versiones de interfaces de funciones porque un tipo primitivo no puede implicar un argumento de tipo general, por lo que necesitamos estas versiones de interfaces de funciones. Muchas versiones diferentes de las interfaces de funciones son instrumentales y se usan comúnmente en tipos primitivos como double, int, long. Las diferentes secuencias de estos tipos primitivos también se utilizan en el argumento.

Estas versiones son:

Bifunción

La Bi-Función está sustancialmente relacionada con una Función. Además, se necesitan dos argumentos, mientras que Function acepta un argumento.

El prototipo y la sintaxis de Bi-Function se detallan a continuación:

@FunctionalInterface public interface BiFunction { R apply(T t, U u); ....... }>

En el código de interfaz anterior, T y U son las entradas, y solo hay una salida que es R.

Operador unario y operador binario

También hay otras dos interfaces funcionales que se denominan Operador unario y Operador binario. Ambos amplían la función y la bifunción, respectivamente. En palabras simples, el operador unario extiende la función y el operador binario extiende la función bifunción.

El prototipo del operador unario y operador binario se menciona a continuación:

i. Operador unario

@FunctionalInterface public interface UnaryOperator extends Function { ……... }>

ii . Operador binario

@FunctionalInterface public interface BinaryOperator extends BiFunction { ……... }>

Podemos entender en el ejemplo anterior que el operador unario acepta solo un argumento y devuelve un solo argumento. Aún así, en Operador Unario, tanto los valores de entrada como los de salida deben ser idénticos y del mismo tipo.

Por otro lado, el operador binario toma dos valores y devuelve un valor comparable a Bi-Función pero similar a un operador unario, los tipos de valores de entrada y salida deben ser idénticos y del mismo tipo.

4. Proveedor

La interfaz funcional del proveedor también es un tipo de interfaz funcional que no recibe ninguna entrada ni argumento y, sin embargo, devuelve una única salida. Este tipo de interfaz funcional se utiliza generalmente en la generación diferida de valores. Las interfaces funcionales del proveedor también se utilizan para definir la lógica para la generación de cualquier secuencia. Por ejemplo: la lógica detrás de la Serie Fibonacci se puede generar con la ayuda de Stream. método de generación, que se implementa mediante la interfaz funcional del proveedor.

Las diferentes extensiones de la interfaz funcional de Proveedor contienen muchas otras funciones de proveedores como BooleanSupplier, DoubleSupplier, LongSupplier e IntSupplier. El tipo de retorno de todas estas especializaciones adicionales son únicamente sus primitivas correspondientes.

La sintaxis/prototipo de la interfaz funcional del proveedor es:

maní vs maní
@FunctionalInterface public interface Supplier{ // gets a result …………. // returns the specific result ………… T.get(); }>

A continuación se muestra la implementación del tema anterior:

Java




// A simple program to demonstrate the use> // of predicate interface> import> java.util.*;> import> java.util.function.Predicate;> class> Test {> >public> static> void> main(String args[])> >{> >// create a list of strings> >List names = Arrays.asList(> >'Geek'>,>'GeeksQuiz'>,>'g1'>,>'QA'>,>'Geek2'>);> >// declare the predicate type as string and use> >// lambda expression to create object> >Predicate p = (s) ->s.startsWith(>'G'>);> >// Iterate through the list> >for> (String st : names) {> >// call the test method> >if> (p.test(st))> >System.out.println(st);> >}> >}> }>

>

>

Producción

Geek GeeksQuiz Geek2>

Puntos Importantes/Observación ns:

Aquí hay algunos puntos importantes con respecto a las interfaces funcionales en Java:

  1. En las interfaces funcionales, solo se admite un método abstracto. Si la anotación de una interfaz funcional, es decir, @FunctionalInterface no está implementada o escrita con una interfaz de función, se puede declarar más de un método abstracto dentro de ella. Sin embargo, en esta situación con más de una función, esa interfaz no se llamará interfaz funcional. Se llama interfaz no funcional.
  2. No existe tal necesidad de la anotación @FunctionalInterface ya que es únicamente voluntaria. Esto está escrito porque ayuda a verificar el nivel del compilador. Además de esto, es opcional.
  3. Se puede agregar una cantidad infinita de métodos (ya sean estáticos o predeterminados) a la interfaz funcional. En palabras simples, no hay límite para una interfaz funcional que contenga métodos estáticos y predeterminados.
  4. Anular métodos de la clase principal no viola las reglas de una interfaz funcional en Java.
  5. El java.util.función El paquete contiene muchas interfaces funcionales integradas en Java 8.