logo

Interfejsy funkcjonalne Java

Interfejs funkcjonalny w Javie to interfejs zawierający tylko jedną metodę abstrakcyjną. Interfejsy funkcjonalne mogą mieć wiele metod domyślnych lub statycznych, ale tylko jedną metodę abstrakcyjną.

Począwszy od wersji Java 8, wyrażeń lambda i odwołań do metod można używać do reprezentowania instancji interfejsu funkcjonalnego.



Przykład: użycie interfejsu funkcjonalnego z wyrażeniem Lambda

Java
public class Geeks {    public static void main(String[] args) {    // Using lambda expression to implement Runnable  new Thread(() -> System.out.println('New thread created')).start();  } } 

Wyjście
New thread created 

Wyjaśnienie:

  • Powyższy program demonstruje użycie wyrażenia lambda z interfejsem funkcjonalnym Runnable.
  • Runnable ma jedną abstrakcyjną metodę run(), więc kwalifikuje się jako interfejs funkcjonalny.
  • Lambda ()-> System.out.println('Utworzono nowy wątek') definiuje metodę run().
  • new Thread().start() uruchamia nowy wątek, który wykonuje treść lambda

Notatka:

A F Funkcjonalny interfejs może także rozszerzać kolejny interfejs funkcjonalny.



@Funkcjonalny interfejs Adnotacja

Adnotacja @FunctionalInterface służy do zapewnienia, że ​​interfejs funkcjonalny nie może mieć więcej niż jednej metody abstrakcyjnej. W przypadku, gdy występuje więcej niż jedna metoda abstrakcyjna, kompilator flaguje komunikat „Nieoczekiwana adnotacja @FunctionalInterface”. Jednakże użycie tej adnotacji nie jest obowiązkowe.

Notatka:

Adnotacja @FunctionalInterface jest opcjonalna, ale warto jej używać. Pomaga wychwycić błąd na wczesnym etapie, upewniając się, że interfejs ma tylko jedną abstrakcyjną metodę.



Przykład: definiowanie interfejsu funkcjonalnego z adnotacją @FunctionalInterface

Java
@FunctionalInterface interface Square {  int calculate(int x); } class Geeks {  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);  } } 

Wyjście
25 

Wyjaśnienie :

  • Square to funkcjonalny interfejs z pojedynczą metodą obliczenia (int x).
  • Wyrażenie lambda (int x) -> x * x służy do implementacji metody obliczeniowej.
  • Lambda przyjmuje x jako dane wejściowe i zwraca x * x.

Interfejsy funkcjonalne Java przed wersją Java 8

Przed Javą 8 musieliśmy tworzyć anonimowe obiekty klas wewnętrznych lub implementować te interfejsy. Poniżej znajduje się przykład implementacji interfejsu Runnable przed wprowadzeniem wyrażeń lambda.

Przykład: Program Java demonstrujący funkcjonalny interfejs

Java
class Geeks {  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();  } } 

Wyjście
New thread created 

Wbudowane interfejsy funkcjonalne Java

Od wersji Java SE 1.8 i nowszych istnieje wiele interfejsów konwertowanych na interfejsy funkcjonalne. Wszystkie te interfejsy są oznaczone adnotacją @FunctionalInterface. Interfejsy te są następujące:

  • Możliwość uruchomienia: Ten interfejs zawiera tylko plik uruchomić() metoda.
  • Porównywalny: Interfejs ten zawiera jedynie metodę CompareTo().
  • Odbiornik akcji: Interfejs ten zawiera wyłącznie metodę actionPerformed().
  • Możliwość wywołania: Interfejs ten zawiera jedynie metodę call().

Rodzaje interfejsów funkcjonalnych w Javie

Java SE 8 zawiera cztery główne rodzaje interfejsów funkcjonalnych, które można zastosować w wielu sytuacjach, jak wspomniano poniżej:

  1. Konsument
  2. Orzec
  3. Funkcjonować 
  4. Dostawca

1. Konsument 

The interfejs konsumencki interfejsu funkcjonalnego to ten, który akceptuje tylko jeden argument lub argument gentryfikowany. Interfejs konsumenta nie ma wartości zwracanej. Nic nie zwraca. Istnieją również warianty funkcjonalne Konsumenta Podwójny konsument Konsument wewnętrzny I Długi Konsument . Warianty te akceptują wartości pierwotne jako argumenty. 

Oprócz tych wariantów istnieje jeszcze jeden wariant interfejsu konsumenckiego, znany jako Bi-konsument

Składnia:

Konsument konsument = (wartość) -> System.out.println(wartość);

Ta implementacja interfejsu funkcjonalnego Java Consumer drukuje wartość przekazaną jako parametr do instrukcji print. Ta implementacja wykorzystuje funkcję Lambda języka Java.

2. Orzeczenie 

The Interfejs predykatu reprezentuje funkcję o wartości logicznej jednego argumentu. Jest powszechnie używany do operacji filtrowania w strumieniach. Podobnie jak interfejs funkcjonalny Consumer, interfejs funkcjonalny Predicate ma również pewne rozszerzenia. To są IntPredykat Podwójny predykat I Długie orzeczenie . Te typy predykatów funkcjonalnych interfejsów akceptują jako argumenty tylko prymitywne typy danych lub wartości.  

Składnia: 

interfejs publiczny Predykat{
   test boolowski (T t);
}

Funkcjonalny interfejs predykatu Java można również zaimplementować przy użyciu wyrażeń Lambda.

Orzec predykat = (wartość) -> wartość != null;

3. Funkcja

A funkcjonować to rodzaj funkcjonalnego interfejsu w Javie, który odbiera tylko jeden argument i zwraca wartość po wymaganym przetworzeniu. Wiele różnych wersji interfejsów funkcji ma charakter instrumentalny i jest powszechnie używanych w typach pierwotnych, takich jak double int long.

Składnia:

Funkcjonować funkcja = (wartość) -> wartość * wartość;

  • Dwufunkcyjny: The Dwufunkcyjny jest zasadniczo powiązany z funkcją. Poza tym przyjmuje dwa argumenty, podczas gdy Funkcja akceptuje jeden argument. 
  • Operator jednoargumentowy i operator binarny: Istnieją również dwa inne interfejsy funkcjonalne, które nazywane są jako Operator jednoargumentowy I Operator binarny. Obydwa rozszerzają odpowiednio funkcję i funkcję dwufunkcyjną, gdy zarówno typ wejścia, jak i typ wyjścia są takie same.

4. Dostawca

The Dostawca interfejs funkcjonalny to także rodzaj interfejsu funkcjonalnego, który nie pobiera żadnych danych wejściowych ani argumentów, a mimo to zwraca pojedyncze wyjście. Różne rozszerzenia interfejsu funkcjonalnego dostawcy obsługują wiele innych funkcji dostawców, np Dostawca logiczny Podwójny dostawca Długi dostawca I Dostawca wewnętrzny . Typem zwracanym wszystkich tych dalszych specjalizacji są tylko odpowiadające im elementy pierwotne. 

Składnia:

Dostawcadostawca = () -> 'Witaj świecie!';

Przykład: Używanie interfejsu predykatów do filtrowania ciągów

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

Wyjście
Geek GeeksQuiz Geek2 

Tabela interfejsów funkcjonalnych

Interfejsy funkcjonalne

Opis

Metoda

Możliwość uruchomienia

Reprezentuje zadanie, które może zostać wykonane przez wątek.

pusty bieg()

Porównywalny

Porównuje dwa obiekty w celu uporządkowania.

int porównajTo(T o)

Słuchacz akcji

Obsługuje zdarzenie akcji w programowaniu sterowanym zdarzeniami.

void actionPerformed (ActionEvent e)

Możliwość wywołania

Reprezentuje zadanie, które może zwrócić wynik lub zgłosić wyjątek.

V call() zgłasza wyjątek

Konsument

Akceptuje pojedynczy argument wejściowy i nie zwraca żadnego wyniku.

unieważnij akceptację (T t)

Orzec

Akceptuje pojedynczy argument i zwraca wynik logiczny.

test boolowski (T t)

Funkcjonować

Akceptuje pojedynczy argument i zwraca wynik.

R zastosuj (T t)

Dostawca

Nie przyjmuje żadnych argumentów, ale podaje wynik.

T dostać()

BiKonsument

Akceptuje dwa argumenty i nie zwraca żadnego wyniku.

unieważnij akceptację (T t U u)

BiPredykat

Akceptuje dwa argumenty i zwraca wynik logiczny.

test boolowski (T t U u)

BiFunkcja

Akceptuje dwa argumenty i zwraca wynik.

R zastosuj (T t U u)

Operator jednoargumentowy

Jest to szczególny przypadek funkcji, w której typy danych wejściowych i wyjściowych są takie same.

T dotyczy (T t)

przykład nazwy użytkownika

Operator binarny

Jest to szczególny przypadek BiFunction, w którym typy wejść i wyjść są takie same.

T dotyczy (T t1 T t2)

Powiązane artykuły

  • Java 8
  • Wyrażenia Lambda w Javie