Java na zawsze pozostała językiem programowania obiektowego. Używając obiektowego języka programowania, możemy zadeklarować, że wszystko, co jest obecne w języku programowania Java, podlega rotacji w obiektach, z wyjątkiem niektórych prymitywnych typów danych i prymitywnych metod zapewniających integralność i prostotę. W języku programowania zwanym Java nie istnieją wyłącznie funkcje. Funkcje w języku programowania Java są częścią klasy i jeśli ktoś chce z nich skorzystać, musi użyć klasy lub obiektu klasy, aby wywołać dowolną funkcję.
Interfejsy funkcjonalne Java
A funkcjonalny interfejs to interfejs zawierający tylko jedną metodę abstrakcyjną. Mogą mieć tylko jedną funkcjonalność do pokazania. Od wersji Java 8 i nowszych wyrażenia lambda może być używany do reprezentowania instancji interfejsu funkcjonalnego. Interfejs funkcjonalny może mieć dowolną liczbę metod domyślnych. Możliwość uruchomienia , Słuchacz akcji , I Porównywalny to tylko niektóre przykłady interfejsów funkcjonalnych.
Interfejs funkcjonalny jest dodatkowo uznawany za Pojedyncze interfejsy metod abstrakcyjnych . Krótko mówiąc, są one również znane jako Interfejsy SAM-owe . Funkcjonalne interfejsy w Javie to nowa funkcja, która zapewnia użytkownikom podejście do programowania od podstaw.
Interfejsy funkcjonalne są zawarte w Java SE 8 z wyrażeniami Lambda i odniesieniami do metod, aby uczynić kod bardziej czytelnym, przejrzystym i prostym. Interfejsy funkcjonalne to interfejsy, które zapewniają, że zawierają dokładnie tylko jedną metodę abstrakcyjną. Interfejsy funkcjonalne są używane i wykonywane poprzez reprezentowanie interfejsu za pomocą adnotacja tzw @Funkcjonalny interfejs . Jak opisano wcześniej, interfejsy funkcjonalne mogą zawierać tylko jedną metodę abstrakcyjną. Mogą jednak zawierać dowolną liczbę metod domyślnych i statycznych.
W interfejsach funkcjonalnych nie ma potrzeby używania słowa kluczowegoabstrakt, ponieważ użycie słowa kluczowegoabstrakt jest opcjonalne, ponieważ domyślnie metoda zdefiniowana wewnątrz interfejsu jest tylko abstrakcyjna. Możemy także wywoływać wyrażenia Lambda jako instancję interfejsu funkcjonalnego.
Przykład interfejsów funkcjonalnych Java
Przykład 1:
Przed wersją Java 8 musieliśmy tworzyć anonimowe obiekty klas wewnętrznych lub implementować te interfejsy.
Jawa
// 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();> >}> }> |
>
>Wyjście
New thread created>
Przykład 2:
Możemy przypisać Java 8 i nowsze wyrażenie lambda do jego funkcjonalnego obiektu interfejsu w następujący sposób:
Jawa
// 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();> >}> }> |
>
>Wyjście
New thread created>
Adnotacja @FunctionalInterface
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”. Stosowanie tej adnotacji nie jest jednak obowiązkowe.
Poniżej realizacja powyższego tematu:
Jawa
// 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);> >}> }> |
>
>Wyjście
25>
Niektóre wbudowane interfejsy funkcjonalne Java
Począwszy od wersji Java SE 1.8, istnieje wiele interfejsów konwertowanych na interfejsy funkcjonalne. Wszystkie te interfejsy są oznaczone adnotacją @FunctionalInterface. Interfejsy te są następujące:
- Runnable –> Ten interfejs zawiera tylko metodę run(). Porównywalne –> Ten interfejs zawiera tylko metodę CompareTo(). ActionListener –> Ten interfejs zawiera tylko metodę actionPerformed(). Callable –> Ten interfejs zawiera tylko metodę call().
Java SE 8 zawierała cztery główne rodzaje interfejsów funkcjonalnych które można zastosować w wielu sytuacjach, jak wspomniano poniżej:
- Dostawca funkcji predykatu konsumenckiego
Spośród poprzednich czterech interfejsów, pierwsze trzy interfejsy, tj. Konsument, Predykat i Funkcja, również mają dodatki opisane poniżej:
- Konsument -> Bi-konsument
- Predykat -> Bi-predykat
- Funkcja -> Dwufunkcyjna, operator jednoargumentowy, operator binarny
1. Konsument
Interfejs konsumencki interfejsu funkcjonalnego to taki, który akceptuje tylko jeden argument lub argument gentryfikowany. Interfejs konsumenta nie ma wartości zwracanej. Nic nie zwraca. Istnieją również funkcjonalne warianty Consumer — DoubleConsumer, IntConsumer i LongConsumer. Warianty te akceptują wartości pierwotne jako argumenty.
Oprócz tych wariantów istnieje jeszcze jeden wariant interfejsu konsumenckiego, znany jako Bi-Consumer.
Bi-konsument – Bi-Consumer to najbardziej ekscytujący wariant interfejsu Consumer. Interfejs konsumencki przyjmuje tylko jeden argument, ale z drugiej strony interfejs Bi-Consumer przyjmuje dwa argumenty. Zarówno Konsument, jak i Bi-Konsument nie mają wartości zwrotnej. Nie zwraca również niczego, podobnie jak interfejs konsumenta. Służy do iteracji po wpisach mapy.
Składnia/prototyp konsumenckiego interfejsu funkcjonalnego –
Consumer consumer = (value) ->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
W logice naukowej funkcja, która przyjmuje argument i w zamian generuje wartość logiczną jako odpowiedź, nazywana jest predykatem. Podobnie w języku programowania Java predykatowy interfejs funkcjonalny Java to typ funkcji, która akceptuje pojedynczą wartość lub argument, dokonuje na nim pewnego rodzaju przetwarzania i zwraca odpowiedź logiczną (Prawda/Fałsz). Implementacja interfejsu funkcjonalnego Predicate obejmuje również logikę filtrowania (proces używany do filtrowania komponentów strumienia na podstawie dostarczonego predykatu) w Javie.
Podobnie jak interfejs funkcjonalny Consumer, interfejs funkcjonalny Predicate ma również pewne rozszerzenia. Są to IntPredicate, DoublePredicate i LongPredicate. Te typy predykatów funkcjonalnych interfejsów akceptują jako argumenty tylko prymitywne typy danych lub wartości.
Dwu-predykat – Bi-Predicate jest także rozszerzeniem interfejsu funkcjonalnego Predicate, który zamiast jednego pobiera dwa argumenty, wykonuje pewne przetwarzanie i zwraca wartość logiczną.
Składnia interfejsu funkcjonalnego predykatu –
public interface Predicate { boolean test(T t); }> Funkcjonalny interfejs predykatu można również zaimplementować przy użyciu klasy. Poniżej podano składnię implementacji interfejsu funkcjonalnego predykatu przy użyciu klasy –
public class CheckForNull implements Predicate { @Override public boolean test(Object o) { return o != null; } }> Funkcjonalny interfejs predykatu Java można również zaimplementować przy użyciu wyrażeń Lambda. Poniżej podano przykład implementacji interfejsu funkcjonalnego Predicate –
Predicate predicate = (value) ->wartość != null;>
Ta implementacja interfejsów funkcjonalnych w Javie przy użyciu wyrażeń Java Lambda jest łatwiejsza w zarządzaniu i efektywniejsza niż ta zaimplementowana przy użyciu klasy, ponieważ obie implementacje wykonują tę samą pracę, tj. zwracają ten sam wynik.
3. Funkcja
Funkcja to typ interfejsu funkcjonalnego w języku Java, który odbiera tylko jeden argument i zwraca wartość po wymaganym przetworzeniu. Istnieje wiele wersji interfejsów funkcji, ponieważ typ pierwotny nie może sugerować argumentu typu ogólnego, dlatego potrzebujemy tych wersji interfejsów funkcji. Wiele różnych wersji interfejsów funkcji ma charakter instrumentalny i jest powszechnie używanych w typach pierwotnych, takich jak double, int, long. W argumencie używane są również różne sekwencje tych typów pierwotnych.
Te wersje to:
Dwufunkcyjny
Funkcja dwufunkcyjna jest zasadniczo powiązana z funkcją. Poza tym przyjmuje dwa argumenty, podczas gdy Funkcja akceptuje jeden argument.
Prototyp i składnia funkcji Bi-Function podano poniżej –
@FunctionalInterface public interface BiFunction { R apply(T t, U u); ....... }> W powyższym kodzie interfejsu T i U są wejściami, a jest tylko jedno wyjście, którym jest R.
Operator jednoargumentowy i operator binarny
Istnieją również dwa inne interfejsy funkcjonalne, zwane operatorem jednoargumentowym i operatorem binarnym. Obydwa rozszerzają odpowiednio funkcję i funkcję dwufunkcyjną. Krótko mówiąc, operator jednoargumentowy rozszerza funkcję, a operator binarny rozszerza funkcję dwufunkcyjną.
Prototyp operatora jednoargumentowego i operatora binarnego jest wymieniony poniżej:
I. Operator jednoargumentowy
@FunctionalInterface public interface UnaryOperator extends Function { ……... }> II . Operator binarny
@FunctionalInterface public interface BinaryOperator extends BiFunction { ……... }> Z powyższego przykładu wynika, że operator jednoargumentowy akceptuje tylko jeden argument i zwraca tylko jeden argument. Mimo to w operatorze jednoargumentowym zarówno wartości wejściowe, jak i wyjściowe muszą być identyczne i tego samego typu.
Z drugiej strony operator binarny przyjmuje dwie wartości i zwraca jedną wartość porównywalną z funkcją dwufunkcyjną, ale podobną do operatora jednoargumentowego, typy wartości wejściowych i wyjściowych muszą być identyczne i tego samego typu.
4. Dostawca
Interfejs funkcjonalny dostawcy to także rodzaj interfejsu funkcjonalnego, który nie pobiera żadnych danych wejściowych ani argumentów, a mimo to zwraca pojedyncze dane wyjściowe. Ten typ interfejsu funkcjonalnego jest powszechnie stosowany w leniwym generowaniu wartości. Interfejsy funkcjonalne dostawcy służą także do definiowania logiki generowania dowolnej sekwencji. Na przykład – logikę szeregu Fibonacciego można wygenerować za pomocą strumienia. generate, która jest implementowana przez Funkcjonalny Interfejs Dostawcy.
Różne rozszerzenia interfejsu funkcjonalnego dostawcy obsługują wiele innych funkcji dostawców, takich jak BooleanSupplier, DoubleSupplier, LongSupplier i IntSupplier. Typem zwracanym wszystkich tych dalszych specjalizacji są tylko odpowiadające im elementy pierwotne.
Składnia/prototyp interfejsu funkcjonalnego dostawcy to –
@FunctionalInterface public interface Supplier{ // gets a result …………. // returns the specific result ………… T.get(); }> Poniżej realizacja powyższego tematu:
Jawa
// 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);> >}> >}> }> |
>
>Wyjście
ukryte aplikacje
Geek GeeksQuiz Geek2>
Ważne punkty/obserwacje nie:
Oto kilka istotnych punktów dotyczących interfejsów funkcjonalnych w Javie:
- W interfejsach funkcjonalnych obsługiwana jest tylko jedna metoda abstrakcyjna. Jeżeli adnotacja interfejsu funkcjonalnego, tj. @FunctionalInterface nie jest zaimplementowana lub napisana z interfejsem funkcji, można w niej zadeklarować więcej niż jedną metodę abstrakcyjną. Jednakże w tej sytuacji, w której występuje więcej niż jedna funkcja, interfejs ten nie będzie nazywany interfejsem funkcjonalnym. Nazywa się to niefunkcjonalnym interfejsem.
- Nie ma takiej potrzeby stosowania adnotacji @FunctionalInterface, ponieważ jest ona dobrowolna. Zostało to napisane, ponieważ pomaga w sprawdzeniu poziomu kompilatora. Poza tym jest to opcjonalne.
- Do interfejsu funkcjonalnego można dodać nieskończoną liczbę metod (statycznych lub domyślnych). Krótko mówiąc, nie ma ograniczeń co do funkcjonalnego interfejsu zawierającego metody statyczne i domyślne.
- Przesłanianie metod z klasy nadrzędnej nie narusza zasad interfejsu funkcjonalnego w Javie.
- The funkcja java.util pakiet zawiera wiele wbudowanych interfejsów funkcjonalnych w Javie 8.