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
Javapublic 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
Javaclass 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:
- Konsument
- Orzec
- Funkcjonować
- 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:
Dostawca
dostawca = () -> 'Witaj świecie!';
Przykład: Używanie interfejsu predykatów do filtrowania ciągów
Javaimport 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