{"id":13765,"date":"2022-05-18T07:00:23","date_gmt":"2022-05-18T05:00:23","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=13765"},"modified":"2023-01-02T13:59:46","modified_gmt":"2023-01-02T12:59:46","slug":"wyrazenie-lambda-w-javie","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/wyrazenie-lambda-w-javie\/","title":{"rendered":"Wyra\u017cenie lambda w Javie"},"content":{"rendered":"\n<p>Wyra\u017cenia lambda zosta\u0142y dodane do Javy w wersji 8. Wprowadzenie tej funkcjonalno\u015bci to krok w stron\u0119 programowania funkcyjnego w Javie.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Instrukcja jest blokiem kodu, kt\u00f3ry mo\u017cna przekazywa\u0107 mi\u0119dzy cz\u0119\u015bciami programu w celu p\u00f3\u017aniejszego wykorzystania dowoln\u0105 liczb\u0119 razy, bez przynale\u017cno\u015bci do \u017cadnej klasy. Lambda mo\u017ce by\u0107 przekazywana jako obiekt i wywo\u0142ywana, kiedy tego chcemy. Przyjmuje parametry i zwraca warto\u015bci. Mo\u017cemy j\u0105 przypisywa\u0107 do zmiennych.<\/p>\n\n\n\n<p>Najwa\u017cniejszymi zaletami wyra\u017ce\u0144 lambda s\u0105:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Mo\u017cliwo\u015b\u0107 pisania kodu w spos\u00f3b funkcyjny \u2013 pozwala to na pisanie bardziej zwi\u0119z\u0142ego kodu, czytelniejszego dla osoby, kt\u00f3ra go czyta.<\/li><li>Tworzenie mniejszej liczby klas.<\/li><li>Wy\u017csza wydajno\u015b\u0107 w pracy z kolekcjami.<\/li><li>Reu\u017cywalno\u015b\u0107 wyra\u017ce\u0144.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Sk\u0142adnia wyra\u017cenia lambda<\/h2>\n\n\n\n<p>Wyra\u017cenie lambda ma posta\u0107:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>Parametr -&gt; wyra\u017cenie<\/em><\/pre>\n\n\n\n<p>Parametrami s\u0105 wymagane dane, a wyra\u017cenie to cia\u0142o metody, czyli kod, kt\u00f3ry okre\u015bla dzia\u0142anie wyra\u017cenia. Mo\u017cliwe jest wywo\u0142anie lambdy:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Bez parametr\u00f3w:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>() -&gt; {wyra\u017cenie}<\/em><\/pre>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nRunnable lambdaWithoutParameters = () -&gt; System.out.println(&quot;Lambda without parameters&quot;);\nlambdaWithoutParameters.run();\n<\/pre><\/div>\n\n\n<p>Wydrukuje \u201eLambda without parameters\u201d. Nie mamy tutaj \u017cadnego parametru, a w wyra\u017ceniu wypisujemy tylko wiadomo\u015b\u0107 do konsoli.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Z jednym parametrem:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>(parametr) -&gt; {wyra\u017cenie}<\/em><\/pre>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nprintable lambdaWithParametr = (String param) -&gt; System.out.println(&quot;Lambda with &quot; + param);\nlambdaWithParametr.printSomething(&quot;parametr&quot;);\n<\/pre><\/div>\n\n\n<p>Wydrukuje \u201eLambda with parametr\u201d. Przekazujemy parametr typu String i u\u017cywamy go w wyra\u017ceniu.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Z kilkoma parametrami:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>(parametr, parametr) -&gt; {wyra\u017cenie}<\/em><\/pre>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nBiConsumer lambdaWithParameters =\n        (String param1, Integer param2) -&gt; {\n            for (int i = 0; i &lt;= param2; i++) {\n                System.out.println(&quot;Lambda with &quot; + param1);\n            }\n        };\nlambdaWithParameters.accept(&quot;parameters&quot;, 5);\n<\/pre><\/div>\n\n\n<p>Wydrukuje \u201eLambda with parameters\u201d 5 razy. Przekazujemy do wyra\u017cenia dwa parametry, String oraz Integer. Parametr pierwszy dodajemy do wypisywania w konsoli, a drugi oznacza ilo\u015b\u0107 powt\u00f3rze\u0144.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Przyk\u0142ad zastosowania wyra\u017cenia lambda<\/h2>\n\n\n\n<p>Poni\u017cej przedstawiam przyk\u0142ad u\u017cycia wyra\u017cenia lambda do wypisania do konsoli wszystkich warto\u015bci zawartych w li\u015bcie metod\u0105 <em>forEach()<\/em>.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Tworzymy list\u0119 zawieraj\u0105c\u0105 kilka liczb ca\u0142kowitych:<\/li><\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nList&lt;Integer&gt; numbers = List.of(1, 2, 3, 4, 5);\n<\/pre><\/div>\n\n\n<ul class=\"wp-block-list\"><li>Wypisujemy wszystkie liczby za pomoc\u0105 lambdy:<\/li><\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nnumbers.forEach(n -&gt; System.out.println(n));\n<\/pre><\/div>\n\n\n<p>Parametrem wyra\u017cenia jest element listy oznaczony jako <em>n<\/em>. Wyra\u017ceniem jest wywo\u0142anie wypisania do konsoli argumentu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Interfejsy funkcyjne<\/h2>\n\n\n\n<p>Interfejs funkcyjny to interfejs zawieraj\u0105cy tylko jedn\u0105 metod\u0119 abstrakcyjn\u0105 (mo\u017ce jednak zawiera\u0107 wiele metod z klasy Object). Nazywane s\u0105 r\u00f3wnie\u017c interfejsami SAM (Single Abstract Method Interface). Aby zaznaczy\u0107, \u017ce interfejs ma by\u0107 funkcyjny nale\u017cy doda\u0107 do niego adnotacje @FunctionalInterface. Adnotacja nie jest obowi\u0105zkowa, ale zapewnia, \u017ce kompilator wyrzuci b\u0142\u0105d na poziomie kompilacji, kiedy interfejs nie b\u0119dzie spe\u0142nia\u0142 warunk\u00f3w interfejsu funkcyjnego.<\/p>\n\n\n\n<p>Przyk\u0142ad poprawnego interfejsu funkcyjnego:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@FunctionalInterface\ninterface printable {\n    void printSomething(String msg);\n\n    int hashCode();\n    String toString();\n    boolean equals(Object obj);\n}\n<\/pre><\/div>\n\n\n<p>Wskazany wy\u017cej interfejs posiada jedn\u0105 metod\u0119 abstrakcyjn\u0105\u00a0<em>printSomething()<\/em>\u00a0oraz kilka metod z klasy\u00a0<em>Object<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Podstawowe kategorie interfejs\u00f3w funkcyjnych<\/h2>\n\n\n\n<p>Do podstawowych kategorii interfejs\u00f3w funkcyjnych nale\u017c\u0105 poni\u017csze:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Supplier<\/li><\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@FunctionalInterface\npublic interface Supplier&lt;T&gt; {\n \n    T get();\n}\n<\/pre><\/div>\n\n\n<p>Widzimy, \u017ce metoda nie przyjmuje \u017cadnych parametr\u00f3w i zwraca obiekt okre\u015blonego przez nas typu.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nSupplier&lt;String&gt; s = () -&gt; &quot;Hello world!&quot;;\nSystem.out.println(s.get());\n<\/pre><\/div>\n\n\n<p>Powy\u017cszy przyk\u0142ad wydrukuje do konsoli \u201eHello world!\u201d.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Consumer<\/li><\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@FunctionalInterface\npublic interface Consumer&lt;T&gt; {\n \n    void accept(T t);\n}\n<\/pre><\/div>\n\n\n<p>Interfejs przyjmuje argument i nie zwraca \u017cadnego obiektu.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nConsumer&lt;String&gt; print = x -&gt; System.out.println(x);\nprint.accept(&quot;Hello world!&quot;);\n<\/pre><\/div>\n\n\n<p>Zastosowany przyk\u0142ad wydrukuje do konsoli \u201eHello world!\u201d.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Predicate<\/li><\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@FunctionalInterface\npublic interface Predicate&lt;T&gt; {\n \n    boolean test(T t);\n      \u2026\n}\n<\/pre><\/div>\n\n\n<p>Interfejs przyjmuje parametr na wej\u015bciu i zwraca warto\u015b\u0107 logiczn\u0105 prawda\/fa\u0142sz na wyj\u015bciu.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nPredicate&lt;Integer&gt; isOdd = number -&gt; number % 2 != 0;\nSystem.out.println(isOdd.test(3));\n<\/pre><\/div>\n\n\n<p>Wskazany przyk\u0142ad wydrukuje do konsoli \u201etrue\u201d.<\/p>\n\n\n\n<p>Metod\u0119 Predicate mo\u017cemy \u0142\u0105czy\u0107 za pomoc\u0105 \u201eand\u201d:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nPredicate&lt;Integer&gt; isOdd = number -&gt; number % 2 == 0;\nPredicate&lt;Integer&gt; isPositive = number -&gt; number &gt; 0;\nSystem.out.println(isOdd.and(isPositive).test(4));\n<\/pre><\/div>\n\n\n<p>Najpierw sprawdzane jest, czy liczba jest parzysta, a p\u00f3\u017aniej, czy jest wi\u0119ksza od zera. Wynik to \u201etrue\u201d.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Function<\/li><\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@FunctionalInterface\npublic interface Function&lt;T, R&gt; {\n    R apply(T t);\n      \u2026\n}\n<\/pre><\/div>\n\n\n<p>Interfejs przyjmuje jeden argument i zwraca warto\u015b\u0107 po dokonaniu operacji.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nFunction&lt;Integer, Double&gt; multiplyByTen = value -&gt; value * 10.0;\nDouble d = multiplyByTen.apply(5);\n<\/pre><\/div>\n\n\n<p>owy\u017cszy przyk\u0142ad przypisze do zmiennej \u201ed\u201d warto\u015b\u0107 \u201e50.0\u201d.<\/p>\n\n\n\n<p>Mo\u017cemy r\u00f3wnie\u017c \u0142\u0105czy\u0107 interfejsy Function za pomoc\u0105 \u201eandThen\u201d:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nFunction&lt;Integer, Integer&gt; addOne = value -&gt; value + 1;\nFunction&lt;Integer, Double&gt; multiplyByTen = value -&gt; value * 10.0;\nSystem.out.println(addOne.andThen(multiplyByTen).apply(5));\n<\/pre><\/div>\n\n\n<p>W tym przypadku najpierw dodajemy 1 do naszej liczby, a nast\u0119pnie mno\u017cymy wynik przez 10. W konsoli zostanie wy\u015bwietlone \u201e60.0\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wzorce projektowe z u\u017cyciem lambd<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Strategia<\/h3>\n\n\n\n<p>Wzorzec strategii pozwala nam na zmian\u0119 zachowania algorytmu w czasie wykonywania (runtime) oraz na wyeliminowanie instrukcji warunkowych w kodzie aplikacji. W pe\u0142nej implementacji wzorca tworzymy interfejs \u201eStrategy\u201d, kt\u00f3ry posiada tylko jedn\u0105 metod\u0119 np. \u201eexecute\u201d i jest wsp\u00f3lny dla wszystkich obs\u0142ugiwanych algorytm\u00f3w.<\/p>\n\n\n\n<p>Nast\u0119pnie interfejs jest implementowany w poszczeg\u00f3lnych klasach dostarczaj\u0105cych konkretne algorytmy. We wzorcu wyr\u00f3\u017cniamy tak\u017ce klas\u0119, kt\u00f3ra korzysta ze stworzonych algorytm\u00f3w. Posiada ona referencje do aktualnie u\u017cywanej strategii.<\/p>\n\n\n\n<p>Zosta\u0142o to zaprezentowane na poni\u017cszym wykresie.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/strategy_diagram.png\"><img decoding=\"async\" width=\"601\" height=\"322\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/strategy_diagram.png\" alt=\"\" class=\"wp-image-18119\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/strategy_diagram.png 601w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/strategy_diagram-300x161.png 300w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/a><figcaption>Ryc. 1 Diagram obrazuj\u0105cy strategi\u0119<\/figcaption><\/figure><\/div>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic interface CountStrategy {\n    Integer count(List&lt;Integer&gt; values);\n}\n \npublic static class CountEvenValues implements CountStrategy {\n \n    @Override\n    public Integer count(List&lt;Integer&gt; values) {\n        return values.stream()\n                .filter(e -&gt; e % 2 == 0)\n                .reduce(0, Integer::sum);\n    }\n}\n \npublic static class CountOddValues implements CountStrategy {\n \n    @Override\n    public Integer count(List&lt;Integer&gt; values) {\n        return values.stream()\n                .filter(e -&gt; e % 2 != 0)\n                .reduce(0, Integer::sum);\n    }\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic static class Count {\n    private final CountStrategy countStrategy;\n \n    public Count(CountStrategy countStrategy) {\n        this.countStrategy = countStrategy;\n    }\n \n    Integer count(List&lt;Integer&gt; values) {\n        return countStrategy.count(values);\n    }\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic static class Main {\n    public static void main(String&#x5B;] args) {\n        Count countEven = new Count(new CountEvenValues());\n        Count countOdd = new Count(new CountOddValues());\n \n        List&lt;Integer&gt; values = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n \n        System.out.println(countEven.count(values));\n        System.out.println(countOdd.count(values));\n    }\n}\n<\/pre><\/div>\n\n\n<p>Powy\u017cszy przyk\u0142ad kodu wydrukuje do konsoli \u201e30\u201d i \u201e25\u201d.<\/p>\n\n\n\n<p>Widzimy tutaj prosty przyk\u0142ad zastosowania wzorca strategii do obliczania sumy listy liczb w zale\u017cno\u015bci od sposobu, w jaki chcemy je liczy\u0107.<\/p>\n\n\n\n<p>Podany przyk\u0142ad mo\u017cemy zapisa\u0107 \u0142atwiej za pomoc\u0105 interfejsu funkcyjnego Predicate:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic static int count(List&lt;Integer&gt; values, Predicate&lt;Integer&gt; condition) {\n    return values.stream()\n            .filter(condition)\n            .reduce(0, Integer::sum);\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic static void main(String&#x5B;] args) {\n    List&lt;Integer&gt; values = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n    System.out.println(count(values, e -&gt; e % 2 == 0));\n    System.out.println(count(values, e -&gt; e % 2 != 0));\n}\n<\/pre><\/div>\n\n\n<p>W konsoli wy\u015bwietl\u0105 si\u0119 warto\u015bci \u201e30\u201d i \u201e25\u201d.<\/p>\n\n\n\n<p>Otrzymujemy wi\u0119c ten sam wynik, u\u017cywaj\u0105c mniejszej ilo\u015bci kodu. Metoda \u201ecount\u201d jest te\u017c w tym przypadku bardziej uniwersalna. Nie musimy do ka\u017cdego warunku tworzy\u0107 osobnych klas, u\u017cywamy tylko r\u00f3\u017cnych warunk\u00f3w poprzez przekazany interfejs Predicate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dekorator<\/h2>\n\n\n\n<p>Wzorzec dekorator pozwala nam na dodawanie nowych obowi\u0105zk\u00f3w obiektom poprzez opakowywanie ich w specjalnych obiektach wrapuj\u0105cych, kt\u00f3re definiuj\u0105 odpowiednie zachowania.<\/p>\n\n\n\n<p>Zastosowanie mo\u017cemy zobaczy\u0107 na poni\u017cszym wykresie.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/decorator_diagram.drawio.png\"><img decoding=\"async\" width=\"761\" height=\"381\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/decorator_diagram.drawio.png\" alt=\"\" class=\"wp-image-18121\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/decorator_diagram.drawio.png 761w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/decorator_diagram.drawio-300x150.png 300w\" sizes=\"(max-width: 761px) 100vw, 761px\" \/><\/a><figcaption>Ryc. 2 Diagram obrazuj\u0105cy u\u017cycie dekoratora<\/figcaption><\/figure><\/div>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic interface Book {\n    String printBook();\n}\n \npublic static class BasicBook implements Book {\n \n    @Override\n    public String printBook() {\n        return &quot;Basic Book&quot;;\n    }\n}\n \npublic static abstract class BookDecorator implements Book {\n    private final Book book;\n \n    public BookDecorator(Book book) {\n        this.book = book;\n    }\n \n    @Override\n    public String printBook() {\n        return book.printBook();\n    }\n}\n \npublic static class FictionBookDecorator extends BookDecorator {\n \n    public FictionBookDecorator(Book book) {\n        super(book);\n    }\n \n    @Override\n    public String printBook() {\n        return &quot;Fiction &quot; + super.printBook();\n    }\n}\n \npublic static class ItBookDecorator extends BookDecorator {\n \n    public ItBookDecorator(Book book) {\n        super(book);\n    }\n \n    @Override\n    public String printBook() {\n        return &quot;IT &quot; + super.printBook();\n    }\n}\n \npublic static class SoftCoverBookDecorator extends BookDecorator {\n \n    public SoftCoverBookDecorator(Book book) {\n        super(book);\n    }\n \n    @Override\n    public String printBook() {\n        return super.printBook() + &quot; with soft cover&quot;;\n    }\n}\n \npublic static class HardCoverBookDecorator extends BookDecorator {\n \n    public HardCoverBookDecorator(Book book) {\n        super(book);\n    }\n \n    @Override\n    public String printBook() {\n        return super.printBook() + &quot; with hard cover &quot;;\n    }\n}\n \npublic static void main(String&#x5B;] args) {\n    BasicBook book = new BasicBook();\n \n    HardCoverBookDecorator hardCoverFictionBook = new HardCoverBookDecorator(new FictionBookDecorator(book));\n    SoftCoverBookDecorator softCoverItBook = new SoftCoverBookDecorator(new ItBookDecorator(book));\n \n    List&lt;Book&gt; books = Arrays.asList(hardCoverFictionBook, softCoverItBook);\n \n    books.forEach(b -&gt; System.out.println(b.printBook()));\n}\n<\/pre><\/div>\n\n\n<p>Powy\u017cszy przyk\u0142ad wydrukuje do konsoli \u201eFiction Basic Book with hard cover\u201d i \u201eIT Basic Book with soft cover\u201d.<\/p>\n\n\n\n<p>Musimy tworzy\u0107 wiele klas, kt\u00f3re rozbuduj\u0105 nasz bazowy obiekt. W przypadku, kiedy zagnie\u017cd\u017camy wi\u0119cej ni\u017c jednego dekoratora, aby stworzy\u0107 finalny obiekt, nie b\u0119dzie to wygl\u0105da\u0142o czytelnie.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic interface Book {\n    String printBook();\n \n    static Book fictionBook(Book book) {\n        return new Book() {\n            @Override\n            public String printBook() {\n                return &quot;Fiction &quot; + book.printBook();\n            }\n        };\n    }\n \n    static Book withSoftCover(Book book) {\n        return new Book() {\n            @Override\n            public String printBook() {\n                return book.printBook() + &quot; with soft cover&quot;;\n            }\n        };\n    }\n}\n \npublic static class BasicBook implements Book {\n \n    @Override\n    public String printBook() {\n        return &quot;Basic book&quot;;\n    }\n}\n \npublic static class BookDecorator {\n    private final Function&lt;Book, Book&gt; attributes;\n \n    private BookDecorator(Function&lt;Book, Book&gt;... desiredAttributes) {\n        this.attributes = Stream.of(desiredAttributes)\n                .reduce(Function.identity(), Function::andThen);\n    }\n \n    public static String printBook(Book book, Function&lt;Book, Book&gt;... desiredAttributes) {\n        return new BookDecorator(desiredAttributes).printBook(book);\n    }\n \n    private String printBook(Book book) {\n        return this.attributes.apply(book).printBook();\n    }\n}\n \npublic static void main(String&#x5B;] args) {\n    String finishedBook = BookDecorator.printBook(new BasicBook(), Book::fictionBook, Book::withSoftCover);\n \n    System.out.println(finishedBook);\n}\n<\/pre><\/div>\n\n\n<p>W tym przypadku w konsoli pojawi si\u0119 napis \u201eFiction Basic book with soft cover\u201d.<br>Przy u\u017cyciu lambd kod znacz\u0105co si\u0119 skraca, a tworzenie skomplikowanych obiekt\u00f3w jest bardziej czytelne.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Podsumowanie<\/h2>\n\n\n\n<p>Wyra\u017cenia lamdba zmieni\u0142y spos\u00f3b programowania w j\u0119zyku Java. Pozwalaj\u0105 pisa\u0107 kr\u00f3tszy kod, daj\u0105 nam mo\u017cliwo\u015b\u0107 lepszej pracy z kolekcjami i strumieniami. Jak wida\u0107 we wskazanych przyk\u0142adach, mo\u017cemy nawet zmienia\u0107 standardowe implementacje niekt\u00f3rych wzorc\u00f3w projektowych tak, aby by\u0142y bardziej zwi\u0119z\u0142e i czytelniejsze.<\/p>\n\n\n\n<p>Jednak\u017ce, korzystanie z wyra\u017ce\u0144 lambda ma r\u00f3wnie\u017c minusy:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Mog\u0105 wydawa\u0107 si\u0119 trudne dla pocz\u0105tkuj\u0105cych programist\u00f3w.<\/li><li>Trudniej je debugowa\u0107 ni\u017c zwyk\u0142e klasy i metody.<\/li><li>Ich testowanie jest trudniejsze.<\/li><\/ul>\n\n\n\n<p>Jak wida\u0107, plusy u\u017cywania lambd przewy\u017cszaj\u0105 minusy. Ci\u0119\u017cko wyobrazi\u0107 sobie teraz powr\u00f3t do czas\u00f3w sprzed Javy 8 i wprowadzenia wyra\u017ce\u0144.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0179r\u00f3d\u0142a<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.ceneo.pl\/96143579\" rel=\"nofollow\" >Java 11 Cookbook \u2013 Nick Samoylov, Mohamed Sanaulla<\/a><\/li><li><a href=\"https:\/\/lubimyczytac.pl\/ksiazka\/4213207\/functional-programming-in-java-harnessing-the-power-of-java-8-lambda-expressions\" rel=\"nofollow\" >Functional Programming in Java: Harnessing the Power Of Java 8 Lambda Expressions \u2013 Venkat Subramaniam<\/a><\/li><li><a href=\"https:\/\/www.ceneo.pl\/101593352\" rel=\"nofollow\" >Head First Design Patterns \u2013 Eric Freeman, Elisabeth Robson<\/a><\/li><li><a href=\"https:\/\/lubimyczytac.pl\/ksiazka\/4946366\/java-podstawy-wydanie-xi\" rel=\"nofollow\" >Java podstawy \u2013 Cay S. Horstmann<\/a><\/li><\/ul>\n\n\n\n<p>***<\/p>\n\n\n\n<p>A je\u015bli interesuje Ci\u0119&nbsp;<a href=\"https:\/\/sii.pl\/blog\/en\/webrtc-what-stands-behind-most-video-conferencing-software-setting-up-a-simple-connection-with-javascript-kotlin\/?category=hard-development\">wykorzystanie JavaScriptu w video konferencjach<\/a>, zach\u0119camy do przeczytania artyku\u0142u naszego eksperta.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;13765&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;12&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 12)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Wyra\u017cenie lambda w Javie&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 12)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Wyra\u017cenia lambda zosta\u0142y dodane do Javy w wersji 8. Wprowadzenie tej funkcjonalno\u015bci to krok w stron\u0119 programowania funkcyjnego w Javie.<\/p>\n","protected":false},"author":358,"featured_media":14769,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[287,330,1267],"class_list":["post-13765","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-software-development","tag-java","tag-wyrazenie-lambda"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/05\/Wyrazenie-lambda-w-Javie-1.png","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/13765"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/358"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=13765"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/13765\/revisions"}],"predecessor-version":[{"id":18123,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/13765\/revisions\/18123"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/14769"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=13765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=13765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=13765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}