JavaRush /Java Blog /Random-IT /Pausa caffè #182. Interfacce funzionali in Java

Pausa caffè #182. Interfacce funzionali in Java

Pubblicato nel gruppo Random-IT
Fonte: DZone Ecco una panoramica delle interfacce funzionali in Java: scopo, esempi, espressioni lambda e un elenco di interfacce predefinite. Pausa caffè #182.  Interfacce funzionali in Java - 1Essendo un linguaggio di programmazione orientato agli oggetti, Java in precedenza non poteva avere funzioni indipendenti perché tutto, tranne alcuni tipi di dati e metodi primitivi, nel linguaggio ruota attorno a classi e oggetti. Tuttavia, Java 8 ha introdotto un nuovo concetto chiamato interfaccia funzionale e anche alcune altre funzionalità come espressioni Lambda, API Time, API Stream e così via. Quali sono queste interfacce funzionali e come definirle? Scopriamolo!

Cos'è un'interfaccia?

Un'interfaccia è un insieme di regole che determinano l'interazione degli elementi del sistema. È noto anche come struttura di una classe contenente metodi astratti e costanti statiche. Un'interfaccia può contenere uno o più metodi astratti. Le interfacce consentono inoltre di impostare i requisiti per le classi, ovvero quali metodi sono richiesti dalla classe. In poche parole, un'interfaccia è come un contratto che deve essere rispettato da ogni classe di implementazione. Ecco un esempio:
Interface A1
{
void method1();
String method2(String X);
}

Class A1 implements A
{
@Override
public void method1(){}
@Override
public String method2(String X) { return x; }
}
Se la classe che implementa l'interfaccia non dichiara tutti i metodi dell'interfaccia, il codice non verrà eseguito e genererà un errore: “ errore: A1 non è astratto e non sovrascrive un metodo astratto in A1. " (errore: A1 non è astratto e non sovrascrive un metodo astratto in A1). Prima di JDK 8, le interfacce non potevano definire implementazioni, ma ora è possibile aggiungere implementazioni predefinite per i metodi di interfaccia. Possiamo anche definire metodi statici e predefiniti, che può chiamare senza un oggetto nell'interfaccia Le interfacce vengono utilizzate principalmente per ottenere l'ereditarietà multipla e l'accoppiamento libero nel codice. Ora che abbiamo una chiara comprensione delle interfacce, vediamo cos'è un'interfaccia funzionale e come funziona.

Cos'è un'interfaccia funzionale?

L'interfaccia funzionale è nota anche come interfaccia SAM (Single Abstract Method). Come suggerisce il nome, può avere al massimo un metodo astratto. Un'interfaccia funzionale può avere diversi metodi statici e predefiniti con un'implementazione, nonché un metodo astratto aggiuntivo. Per contrassegnare un'interfaccia come funzionale, viene utilizzata l' annotazione @FunctionalInterface . È necessario per evitare di dichiarare erroneamente metodi aggiuntivi. Ciò che rende l'interfaccia funzionale così popolare è la possibilità di utilizzare espressioni lambda per creare interfacce senza utilizzare implementazioni di classi anonime e ingombranti. L'uso della parola chiave abstract nelle interfacce funzionali è facoltativo poiché i metodi definiti all'interno di un'interfaccia sono astratti per impostazione predefinita.

Cosa sono le espressioni lambda?

Un'espressione lambda è un metodo senza nome o anonimo che non viene eseguito da solo, ma viene utilizzato per implementare determinati metodi di un'interfaccia funzionale. È definito come segue:
(parameter list) -> lambda body
L'operatore freccia ( -> ) visualizzato nel codice è noto come operatore lambda. Ad esempio, se abbiamo il seguente metodo:
double getGoldenRatioValue() {
return 1.61803;
}
Usando un'espressione lambda, possiamo scriverla in questo modo:
() -> 1.61803
Come puoi vedere, il metodo nella funzione lambda non ha parametri, quindi il lato sinistro dell'istruzione è vuoto. Poiché il lato destro determina l'azione, in questo esempio restituirà il valore della sezione aurea: 1.61803. Prima di Java 8, l'implementazione delle interfacce o la creazione di oggetti di classe interna era cruciale, ma con Java 8 tutto ciò che dobbiamo fare ora è assegnare espressioni lambda alle interfacce funzionali.

Esempi di interfacce funzionali

Per creare interfacce funzionali, puoi utilizzare l' annotazione @FunctionalInterface o utilizzare le interfacce funzionali predefinite di Java.

Esempio 1

  • Per prima cosa taggheremo @FunctionalInterface e creeremo un'interfaccia chiamata MyInterface che verrà chiamata dal metodo astratto getGoldenRationValue() .
  • Quindi creeremo una classe pubblica main per eseguire il metodo.
  • Per utilizzare un'espressione lambda in un'interfaccia funzionale, dichiareremo un riferimento a MyInterfaceDemo e quindi assegneremo l'espressione lambda a quel riferimento.
  • Infine, stamperemo il valore della sezione aurea utilizzando l'interfaccia di riferimento.
import java.lang.FunctionalInterface;

// Creation и маркировка функционального интерфейса
@FunctionalInterface

interface MyInterface {
// Это абстрактный метод
double getGoldenRatioValue();
}

public class Main {
public static void main( String[] args ) {

//декларируем ссылку на функциональный интерфейс
MyInterface ref;
//используем Lambda Expression
ref = () -> 1.61803;

System.out.println("Value of Golden Ratio = " + ref.getGoldenRatioValue());
}
}
Conclusione:
Valore della sezione aurea = 1,61803

Esempio 2

  • In questo esempio, utilizzeremo l'interfaccia della funzione predefinita ToDoubleFunction , che accetta un argomento T e restituisce un double come output.
  • ToDoubleFuntion contiene un metodo astratto chiamato applyasDouble() .
  • Infine stampiamo l'intera lunghezza del messaggio, compresi gli spazi.
import java.util.function.ToDoubleFunction;
public class MyInterface2 {

public static void main(String[] args) {

ToDoubleFunction<String> length = x -> x.length();

System.out.println(length.applyAsDouble("This is an example of predefined functional interface."));
}
}
Conclusione:
54.0

Elenco delle interfacce funzionali preinstallate

Ora che sappiamo come definire le interfacce funzionali, vediamo quante interfacce funzionali predefinite (incorporate) esistono. Esistono 4 tipi principali di interfacce funzionali che possono essere implementate in diverse situazioni: Consumatore , Predicato , Funzione e Fornitore . Tra queste quattro interfacce, Consumer , Function e Predicate hanno interfacce di funzioni aggiuntive. Ecco un elenco di tutte le interfacce integrate o predefinite in Java. Nota. T, U e R menzionati nella tabella seguente rappresentano rispettivamente il tipo del primo argomento (T), del secondo argomento (U) e del risultato (R) dell'operazione.
Interfaccia Tipo
Percorribile
Biconsumatore(T, U) T, U→
BiFunzione(T, U, R) T, U → R
Operatore Binario T, T <→ R
BiPredicato<T, U> T, U → booleano
BooleanSupplier → booleano
Consumatore T→
DoubleBinaryOperator doppio, doppio → doppio
DoppioConsumatore doppio →
Doppia funzione doppio → R
Doppio predicato doppio → booleano
DoubleSupplier booleano →
DoubleToIntFunction doppio → int
Funzione DoubleToLong doppio → lungo
DoubleUnaryOperator doppio → doppio
Funzione<T, R> T→R
IntBinaryOperator int → int
IntConsumatore int →
Funzione int int→R
IntPredicato int → booleano
IntSupplier → int
IntToDoubleFunction int → doppio
Funzione IntToLong int → lungo
IntUnaryOperator int → int
LongBinaryOperator lungo, lungo → lungo
LongConsumer lungo →
Funzione lunga lungo → R
Predicato lungo lungo →
LongSupplier → lungo
LongToDoubleFunction lungo → doppio
LongToIntFunction lungo → int
LongUnaryOperator lungo → lungo
ObjDoubleConsumer T, doppio →
ObjIntConsumer T, int →
ObjLongConsumer T, lungo →
Predicato T → booleano
Fornitore →T
ToDoubleBiFunction<T, U> T, U → doppio
ToDoubleFunction T → doppio
ToIntBiFunzione<T, U> T, U → int
ToIntFunction T → int
ToLongBiFunction<T, U> T, U → lungo
ToLongFunction T → lungo
UnaryOperator T→T

Riassumiamo

Alcuni punti chiave da ricordare da questo post:
  • L'interfaccia funziona come un meccanismo di astrazione.
  • Un'interfaccia funzionale può avere diversi metodi statici e predefiniti con un'implementazione, nonché un metodo astratto aggiuntivo.
  • I metodi definiti all'interno di un'interfaccia funzionale sono astratti per impostazione predefinita, quindi l'utilizzo della parola chiave abstract non è più necessario.
  • Un'espressione lambda è un metodo anonimo che non viene eseguito da solo, ma viene utilizzato per implementare determinati metodi di un'interfaccia funzionale.
  • Per creare interfacce funzionali, puoi utilizzare l' annotazione @FunctionalInterface o utilizzare le interfacce funzionali predefinite di Java.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION