<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Archiwa Optional | To co najważniejsze</title>
	<atom:link href="https://www.danuta-cybulska.com/tag/optional/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.danuta-cybulska.com/tag/optional/</link>
	<description>Blog o wszystkim tym co jest dla mnie najważniejsze w życiu.</description>
	<lastBuildDate>Thu, 19 Feb 2026 12:17:25 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.1</generator>

<image>
	<url>https://www.danuta-cybulska.com/wp-content/uploads/2025/06/3-150x150.png</url>
	<title>Archiwa Optional | To co najważniejsze</title>
	<link>https://www.danuta-cybulska.com/tag/optional/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Learning Log #4: Strumienie, lambdy i funkcyjne programowanie w Java</title>
		<link>https://www.danuta-cybulska.com/programowanie-funkcyjne-java/</link>
					<comments>https://www.danuta-cybulska.com/programowanie-funkcyjne-java/#respond</comments>
		
		<dc:creator><![CDATA[Danuta]]></dc:creator>
		<pubDate>Wed, 29 Apr 2026 16:00:00 +0000</pubDate>
				<category><![CDATA[LearningLog]]></category>
		<category><![CDATA[Programowanie i Rozwój]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[lambda Java]]></category>
		<category><![CDATA[learning log]]></category>
		<category><![CDATA[method references]]></category>
		<category><![CDATA[nauka programowania]]></category>
		<category><![CDATA[Optional]]></category>
		<category><![CDATA[programowanie funkcyjne]]></category>
		<category><![CDATA[streams API]]></category>
		<category><![CDATA[Zajavka]]></category>
		<guid isPermaLink="false">https://www.danuta-cybulska.com/?p=5781</guid>

					<description><![CDATA[<p>Kawa trzecia dzisiaj. Kod na ekranie wygląda&#8230; dziwnie. Zamiast pętli for mam Zamiast: Mam: Witajcie w świecie programowania funkcyjnego w Java. Tydzień 13-14 mojej nauki (po oficjalnym zakończeniu podstaw Zajavka) poświęciłam na zaawansowane tematy: strumienie (Streams API), wyrażenia lambda i Optional. Tematy, które na początku wyglądały jak hieroglify, a teraz&#8230; no cóż, nadal są trudne,...</p>
<p>Artykuł <a href="https://www.danuta-cybulska.com/programowanie-funkcyjne-java/">Learning Log #4: Strumienie, lambdy i funkcyjne programowanie w Java</a> pochodzi z serwisu <a href="https://www.danuta-cybulska.com">To co najważniejsze</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cover is-light"><span aria-hidden="true" class="wp-block-cover__background has-background-dim" style="background-color:#c7cacb"></span><img fetchpriority="high" decoding="async" width="620" height="410" src="https://www.danuta-cybulska.com/wp-content/uploads/2026/02/17.png" class="wp-block-cover__image-background wp-post-image" alt="programowanie funkcyjne Java" data-object-fit="cover" data-object-position="51% 36%" style="object-position:51% 36%;" srcset="https://www.danuta-cybulska.com/wp-content/uploads/2026/02/17.png 620w, https://www.danuta-cybulska.com/wp-content/uploads/2026/02/17-300x198.png 300w, https://www.danuta-cybulska.com/wp-content/uploads/2026/02/17-340x226.png 340w, https://www.danuta-cybulska.com/wp-content/uploads/2026/02/17-370x245.png 370w" sizes="(max-width: 620px) 100vw, 620px" /><div class="wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained"><h2 style="background-color:#abb7c26e" class="has-text-align-center has-link-color wp-elements-1 wp-block-post-title has-text-color has-white-color has-background has-x-large-font-size">Learning Log #4: Strumienie, lambdy i funkcyjne programowanie w Java</h2></div></div>



<p class="wp-block-paragraph">Kawa trzecia dzisiaj. Kod na ekranie wygląda&#8230; dziwnie. Zamiast pętli <code>for</code> mam </p>



<pre class="wp-block-code"><code><code>.stream().filter().map().collect()</code></code></pre>



<p class="wp-block-paragraph">Zamiast:</p>



<pre class="wp-block-code"><code>java<br><br><code>for (int i = 0; i &lt; list.size(); i++) { ... }</code></code></pre>



<p class="wp-block-paragraph">Mam:</p>



<pre class="wp-block-code"><code>java<br><br><code>list.stream().forEach(item -> ...)</code></code></pre>



<p class="wp-block-paragraph"><strong>Witajcie w świecie programowania funkcyjnego w Java.</strong></p>



<p class="wp-block-paragraph">Tydzień 13-14 mojej nauki (po oficjalnym zakończeniu podstaw Zajavka) poświęciłam na zaawansowane tematy: <strong>strumienie (Streams API), wyrażenia lambda i Optional</strong>. Tematy, które na początku wyglądały jak hieroglify, a teraz&#8230; no cóż, nadal są trudne, ale już rozumiem PO CO.</p>



<h2 class="wp-block-heading">Czym są wyrażenia lambda w Java?</h2>



<h3 class="wp-block-heading">Najprostsza definicja:</h3>



<p class="wp-block-paragraph"><strong>Lambda to funkcja bez nazwy, którą można przekazać jako argument.</strong></p>



<p class="wp-block-paragraph">Zamiast pisać:</p>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-2"><code>java

public interface Greeting { 
    void sayHello(String name); 
}

public class PolishGreeting implements Greeting { 
     @Override 
     public void sayHello(String name) { 
         System.out.println("Cześć " + name); 
     } 
}

// Użycie: 
Greeting greeting = new PolishGreeting(); 
greeting.sayHello("Anna");</code></pre>



<p class="wp-block-paragraph">Możesz napisać:</p>



<pre class="wp-block-code"><code>java

<code>Greeting greeting = (name) -> System.out.println("Cześć " + name); </code>
<code>greeting.sayHello("Anna");</code></code></pre>



<p class="wp-block-paragraph"><strong>10 linii → 1 linia. To jest moc lambd.</strong></p>



<h3 class="wp-block-heading">Składnia lambda &#8211; od długiej do krótkiej:</h3>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-3"><code>java

// Wersja pełna (typ parametru + nawias + return) 
(String name) -> { return "Cześć " + name; }

// Bez typu (Java infers - wywnioskuje) 
(name) -> { return "Cześć " + name; }

// Bez return (single expression) 
(name) -> "Cześć " + name

// Jeden parametr = bez nawiasu 
name -> "Cześć " + name</code></pre>



<p class="wp-block-paragraph"><strong>Wszystkie 4 wersje robią TO SAMO.</strong></p>



<h3 class="wp-block-heading">Mój przykład &#8211; filtrowanie terapii:</h3>



<p class="wp-block-paragraph"><strong>Przed lambdą:</strong></p>



<pre class="wp-block-code"><code>java

<code>public class ExpensiveTherapyFilter { </code>   <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">public List&lt;Therapy> filter(List&lt;Therapy> therapies) { </span>
          <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">List&lt;Therapy> result = new ArrayList&lt;>(); </span>
          <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">for (Therapy therapy : therapies) {</span>
              <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;"> if (therapy.getCost() > 70) {</span>
                  <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;"> result.add(therapy);</span>
               <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">} </span>
          <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">} </span>
          <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">return result; </span>
   <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span>
<span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span></code></pre>



<p class="wp-block-paragraph"><strong>Z lambdą:</strong></p>



<pre class="wp-block-code"><code>java

<code>List&lt;Therapy> expensive = therapies.stream()</code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;"> .filter(t -> t.getCost() > 70) </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"><strong>15 linii → 3 linie. Czytelniejsze. Mniej szablonowe.</strong></p>



<h2 class="wp-block-heading">Streams API &#8211; pipeline przetwarzania danych</h2>



<h3 class="wp-block-heading">Czym jest strumień (stream)?</h3>



<p class="wp-block-paragraph"><strong>Strumień to sekwencja elementów</strong> które możesz przetwarzać w pipeline (rurociąg).</p>



<p class="wp-block-paragraph"><strong>Analogia &#8211; taśma produkcyjna:</strong></p>



<p class="wp-block-paragraph">Wyobraź sobie fabrykę:</p>



<ol class="wp-block-list">
<li><strong>Źródło:</strong> Surowce wchodzą na taśmę</li>



<li><strong>Operacje pośrednie:</strong> Czyszczenie → Cięcie → Malowanie</li>



<li><strong>Operacja końcowa:</strong> Pakowanie do pudełka</li>
</ol>



<p class="wp-block-paragraph">W Javie:</p>



<ol class="wp-block-list">
<li><strong>Źródło:</strong> <code>list.stream()</code></li>



<li><strong>Operacje pośrednie:</strong> <code>.filter()</code> → <code>.map()</code> → <code>.sorted()</code></li>



<li><strong>Operacja końcowa:</strong> <code>.collect()</code> lub <code>.forEach()</code></li>
</ol>



<h3 class="wp-block-heading">Podstawowe operacje:</h3>



<p class="wp-block-paragraph"><strong>filter() &#8211; filtrowanie</strong></p>



<pre class="wp-block-code"><code>java

<code>// Tylko terapie droższe niż 70 zł </code>
<code>List&lt;Therapy> expensive = therapies.stream() </code>     .<span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">filter(t -> t.getCost() > 70) </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"><strong>map() &#8211; transformacja</strong></p>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-4"><code>java

// Lista kosztów (z Therapy robi Double) 
   List&lt;Double> costs = therapies.stream() 
        .map(t -> t.getCost()) 
        .collect(Collectors.toList());

// Skrócona wersja (method reference): 
   List&lt;Double> costs = therapies.stream() 
       .map(Therapy::getCost) 
       .collect(Collectors.toList());</code></pre>



<p class="wp-block-paragraph"><strong>sorted() &#8211; sortowanie</strong></p>



<pre class="wp-block-code"><code>java

<code>// Posortowane po cenie (rosnąco) </code>
<code>List&lt;Therapy> sorted = therapies.stream() <span style="background-color: initial; font-family: inherit; font-size: inherit; text-align: initial; color: rgb(102, 102, 102);"> </span>   </code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.sorted(Comparator.comparing(Therapy::getCost)) </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"><strong>forEach() &#8211; akcja na każdym</strong></p>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-5"><code>java

// Wypisz każdą terapię 
   therapies.stream() 
       .forEach(t -> System.out.println(t.getName()));

// Lub krócej: 
   therapies.stream() 
       .forEach(System.out::println);`</code></pre>



<h3 class="wp-block-heading">Łańcuchowanie operacji (chaining):</h3>



<pre class="wp-block-code"><code>java

<code>// Znajdź 3 najdroższe terapie typu "SI" i wypisz ich nazwy </code>
<code>therapies.stream()</code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.filter(t -> t.getType().equals("SI")) // tylko SI </span>
<span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">    .sorted(Comparator.comparing(Therapy::getCost).reversed()) // od najdroższych </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.limit(3) // tylko 3 </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.map(Therapy::getName) // same nazwy </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.forEach(System.out::println); // wypisz</span></code></pre>



<p class="wp-block-paragraph"><strong>Piękno:</strong> Czytasz to jak zdanie po polsku &#8211; &#8222;weź terapie, odfiltruj SI, posortuj po cenie malejąco, weź 3, wyciągnij nazwy, wypisz&#8221;</p>



<h2 class="wp-block-heading">Mój projekt &#8211; analiza kosztów terapii z Streams</h2>



<p class="wp-block-paragraph">Zbudowałam system analizy moich wydatków na terapie używając Streams API.</p>



<pre class="wp-block-code"><code>java

public class TherapyAnalyzer { private List&lt;TherapySession> sessions;

public TherapyAnalyzer(List&lt;TherapySession> sessions) {
    this.sessions = sessions;
}

// 1. Całkowity koszt wszystkich terapii
public double getTotalCost() {
    return sessions.stream()
        .mapToDouble(TherapySession::getCost)
        .sum();
}

// 2. Średni koszt terapii
public double getAverageCost() {
    return sessions.stream()
        .mapToDouble(TherapySession::getCost)
        .average()
        .orElse(0.0);
}

// 3. Najdroższa terapia
public Optional&lt;TherapySession> getMostExpensive() {
    return sessions.stream()
        .max(Comparator.comparing(TherapySession::getCost));
}

// 4. Grupowanie po typie terapii
public Map&lt;String, List&lt;TherapySession>> groupByType() {
    return sessions.stream()
        .collect(Collectors.groupingBy(TherapySession::getType));
}

// 5. Suma kosztów per typ terapii
public Map&lt;String, Double> getCostByType() {
    return sessions.stream()
        .collect(Collectors.groupingBy(
            TherapySession::getType,
            Collectors.summingDouble(TherapySession::getCost)
        ));
}

// 6. Liczba sesji per typ
public Map&lt;String, Long> getCountByType() {
    return sessions.stream()
        .collect(Collectors.groupingBy(
            TherapySession::getType,
            Collectors.counting()
        ));
}

// 7. Terapie w danym miesiącu
public List&lt;TherapySession> getSessionsInMonth(int year, int month) {
    return sessions.stream()
        .filter(s -> s.getDate().getYear() == year)
        .filter(s -> s.getDate().getMonthValue() == month)
        .sorted(Comparator.comparing(TherapySession::getDate))
        .collect(Collectors.toList());
}

// 8. Top 5 najdroższych sesji
public List&lt;TherapySession> getTop5MostExpensive() {
    return sessions.stream()
        .sorted(Comparator.comparing(TherapySession::getCost).reversed())
        .limit(5)
        .collect(Collectors.toList());
}

// 9. Czy są nieopłacone terapie?
public boolean hasUnpaidSessions() {
    return sessions.stream()
        .anyMatch(s -> !s.isPaid());
}

// 10. Wszystkie opłacone?
public boolean allPaid() {
    return sessions.stream()
        .allMatch(TherapySession::isPaid);
}

}</code></pre>



<h3 class="wp-block-heading">Użycie:</h3>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-6"><code>java

// Przykładowe dane 
   List&lt;TherapySession> sessions = List.of( 
        new TherapySession("SI", LocalDate.of(2026, 4, 1), 75.0, true), 
        new TherapySession("Logopeda", LocalDate.of(2026, 4, 3), 65.0, true), 
        new TherapySession("SI", LocalDate.of(2026, 4, 8), 75.0, false), 
        new TherapySession("Pedagog", LocalDate.of(2026, 4, 10), 60.0, true), 
        new TherapySession("Logopeda", LocalDate.of(2026, 4, 15), 65.0, false) 
   );

TherapyAnalyzer analyzer = new TherapyAnalyzer(sessions);

// Analiza 
   System.out.println("Total: " + analyzer.getTotalCost() + " zł"); 
// Output: Total: 340.0 zł

   System.out.println("Average: " + analyzer.getAverageCost() + " zł"); 
// Output: Average: 68.0 zł

   Map&lt;String, Double> costByType = analyzer.getCostByType(); 
   System.out.println("SI: " + costByType.get("SI") + " zł"); 
// Output: SI: 150.0 zł

   System.out.println("Has unpaid: " + analyzer.hasUnpaidSessions()); 
// Output: Has unpaid: true`</code></pre>



<p class="wp-block-paragraph"><strong>Realny użytek:</strong> Teraz mogę w sekundę wygenerować raport miesięczny dla księgowej!</p>



<h2 class="wp-block-heading">Optional &#8211; koniec z NullPointerException?</h2>



<h3 class="wp-block-heading">Problem z null:</h3>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-7"><code>java

public Therapy getMostExpensiveTherapy(List&lt;Therapy> therapies) { 
       Therapy result = null; for (Therapy t : therapies) {
               if (result == null || t.getCost() > result.getCost()) { 
               result = t; 
               } 
       } return result; 
// Co jeśli lista pusta? → null 
}

// Użycie: 
Therapy expensive = getMostExpensiveTherapy(therapies); System.out.println(expensive.getName());   // BOOM! NullPointerException jeśli lista pusta`</code></pre>



<h3 class="wp-block-heading">Rozwiązanie &#8211; Optional:</h3>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-8"><code>java

public Optional&lt;Therapy> getMostExpensiveTherapy(List&lt;Therapy> therapies) {
       return therapies.stream() 
       .max(Comparator.comparing(Therapy::getCost)); 
}

// Użycie - wersja 1 (sprawdź czy jest) 
Optional&lt;Therapy> expensive = getMostExpensiveTherapy(therapies); 
if (expensive.isPresent()) { 
    System.out.println(expensive.get().getName());
} else { 
    System.out.println("No therapies"); 
}

// Użycie - wersja 2 
(functional style) getMostExpensiveTherapy(therapies) 
     .ifPresent(t -> System.out.println(t.getName()));

// Użycie - wersja 3 (default value) 
String name = getMostExpensiveTherapy(therapies) 
       .map(Therapy::getName) 
       .orElse("No therapies");</code></pre>



<p class="wp-block-paragraph"><strong>Optional mówi wyraźnie:</strong> &#8222;Ta metoda może NIE zwrócić wartości&#8221;</p>



<h3 class="wp-block-heading">Kiedy używać Optional:</h3>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>TAK:</strong></p>



<ul class="wp-block-list">
<li>Zwracane wartości metod które mogą być puste</li>



<li>Rezultat wyszukiwania</li>



<li><code>stream().findFirst()</code>, <code>.max()</code>, <code>.min()</code></li>
</ul>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>NIE:</strong></p>



<ul class="wp-block-list">
<li>Pola w klasach (ciężkie, memory overhead)</li>



<li>Parametry metod (null-check prostszy)</li>



<li>Collections (używaj pustej listy zamiast Optional&lt;List&gt;)</li>
</ul>



<h2 class="wp-block-heading">Method references &#8211; skróty lambd</h2>



<p class="wp-block-paragraph">Czasem lambda to tylko przekazanie do innej metody:</p>



<pre class="wp-block-code has-pinnacle-primary-color has-text-color has-link-color wp-elements-9"><code>java

// Lambda 
list.forEach(item -> System.out.println(item));

// Method reference 
list.forEach(System.out::println);`</code></pre>



<h3 class="wp-block-heading">Typy method references:</h3>



<p class="wp-block-paragraph"><strong>1. Static method</strong></p>



<pre class="wp-block-code"><code>java

<code>// Lambda </code>
<code>list.stream().map(s -> Integer.parseInt(s))</code>
<code>// Method reference </code>
<code>list.stream().map(Integer::parseInt)</code></code></pre>



<p class="wp-block-paragraph"><strong>2. Instance method</strong></p>



<pre class="wp-block-code"><code>java

<code>// Lambda </code>
<code>therapies.stream().map(t -> t.getName()) </code>
<code>// Method reference </code>
<code>therapies.stream().map(Therapy::getName)</code></code></pre>



<p class="wp-block-paragraph"><strong>3. Constructor</strong></p>



<pre class="wp-block-code"><code>java

<code>// Lambda </code>
<code>list.stream().map(name -> new Therapy(name))</code>
<code>// Method reference </code>
<code>list.stream().map(Therapy::new)</code></code></pre>



<h2 class="wp-block-heading">Typowe błędy które popełniłam</h2>



<h3 class="wp-block-heading">1. Modyfikowanie źródła w stream</h3>



<p class="wp-block-paragraph"><strong>Błąd:</strong></p>



<pre class="wp-block-code"><code>java

<code>List&lt;Therapy> therapies = new ArrayList&lt;>(originalList);</code> <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">therapies.stream() </span>
      <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.forEach(t -> therapies.add(new Therapy("Copy"))); // ConcurrentModificationException!</span></code></pre>



<p class="wp-block-paragraph"><strong>Lekcja:</strong> Streams NIE mogą modyfikować kolekcji źródłowej.</p>



<h3 class="wp-block-heading">2. Używanie side effects w lambda</h3>



<p class="wp-block-paragraph"><strong>Błąd:</strong></p>



<pre class="wp-block-code"><code>java

<code>int&#91;] counter = {0}; // <span style="background-color: initial; font-family: inherit; font-size: inherit; text-align: initial; color: rgb(102, 102, 102);">zmienna</span><span style="background-color: initial; font-family: inherit; font-size: 0.875rem; text-align: initial;"> zewnętrzna zmienna </span><span style="background-color: initial; font-family: inherit; font-size: inherit; text-align: initial; color: rgb(102, 102, 102);"> </span><span style="background-color: initial; font-family: inherit; font-size: 0.875rem; text-align: initial;">therapies.stream() </span></code>      <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.forEach(t -> counter&#91;0]++); // </span>ŹLE! Efekt uboczny</code></pre>



<p class="wp-block-paragraph"><strong>Lepiej:</strong></p>



<pre class="wp-block-code"><code>java

<code>long count = therapies.stream().count(); // <span style="background-color: initial; font-family: inherit; font-size: inherit; text-align: initial; color: rgb(102, 102, 102);">Sposób funkcjonalny</span></code></code></pre>



<h3 class="wp-block-heading">3. Zapomnienie .collect()</h3>



<p class="wp-block-paragraph"><strong>Błąd:</strong></p>



<pre class="wp-block-code"><code>java

<code>therapies.stream() </code>     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.filter(t -> t.getCost() > 70) </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.map(Therapy::getName); // To NIE zwraca List! To Stream!</span></code></pre>



<p class="wp-block-paragraph"><strong>Poprawka:</strong></p>



<pre class="wp-block-code"><code>java

<code>List&lt;String> names = therapies.stream() </code>     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.filter(t -> t.getCost() > 70) </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.map(Therapy::getName) .collect(Collectors.toList()); // Teraz tak!</span></code></pre>



<h3 class="wp-block-heading">4. Używanie Optional.get() bez sprawdzenia</h3>



<p class="wp-block-paragraph"><strong>Błąd:</strong></p>



<pre class="wp-block-code"><code>java

<code>Optional&lt;Therapy> therapy = findTherapy();System.out.println(therapy.get().getName()); // NoSuchElementException jeśli empty!</code></code></pre>



<p class="wp-block-paragraph"><strong>Lepiej:</strong></p>



<pre class="wp-block-code"><code>java

<code>therapy.ifPresent(t -> System.out.println(t.getName())); </code>
<code>// Lub </code>
<code>String name = therapy.map(Therapy::getName).orElse("Unknown");</code></code></pre>



<h2 class="wp-block-heading">Kiedy używać programowania funkcyjnego, a kiedy imperatywnego?</h2>



<h3 class="wp-block-heading">Użyj functional (streams, lambda):</h3>



<p class="wp-block-paragraph"> <strong>Transformacja danych:</strong></p>



<pre class="wp-block-code"><code>java

<code>List&lt;String> names = therapies.stream() </code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.map(Therapy::getName) </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"> <strong>Filtrowanie:</strong></p>



<pre class="wp-block-code"><code>java

<code>List&lt;Therapy> expensive = therapies.stream() </code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.filter(t -> t.getCost() > 70) </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"><strong>Agregacja:</strong></p>



<pre class="wp-block-code"><code>java

<code>double total = therapies.stream() </code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.mapToDouble(Therapy::getCost) </span>
    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.sum();</span></code></pre>



<h3 class="wp-block-heading">Użyj imperative (pętla for):</h3>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Wczesne wyjście (early exit):</strong></p>



<pre class="wp-block-code"><code>java

<code>for (Therapy t : therapies) { </code>     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">if (t.getName().equals("SI")) { </span>
         <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">return t; // Znalazłem, wychodzę </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span>
<span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span></code></pre>



<p class="wp-block-paragraph">(Stream też może: <code>.filter().findFirst()</code> ale pętla czytelniejsza)</p>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Modyfikacja elementów in-place:</strong></p>



<pre class="wp-block-code"><code>java

<code>for (Therapy t : therapies) {</code>    <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;"> t.markAsPaid(); // Zmieniam obiekt </span>
 <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span></code></pre>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Proste iteracje:</strong></p>



<pre class="wp-block-code"><code>java

<code>for (int i = 0; i &lt; 10; i++) { </code>     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">System.out.println(i); </span>
 <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span></code></pre>



<p class="wp-block-paragraph">(Stream: <code>IntStream.range(0, 10).forEach(System.out::println)</code> &#8211; przesada)</p>



<h2 class="wp-block-heading">Wydajność &#8211; czy streams są szybkie?</h2>



<h3 class="wp-block-heading">Benchmark test (100,000 elementów):</h3>



<p class="wp-block-paragraph"><strong>Pętla FOR:</strong></p>



<pre class="wp-block-code"><code>java

<code>// Czas: ~15ms </code>
<code>List&lt;Integer> result = new ArrayList&lt;>(); for (Integer num : numbers) {</code>       <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;"> if (num % 2 == 0) { </span>
           <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">result.add(num * 2); </span>
        <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span>
  <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">}</span></code></pre>



<p class="wp-block-paragraph"><strong>Stream:</strong></p>



<pre class="wp-block-code"><code>java

<code>// Czas: ~25ms </code>
<code>List&lt;Integer> result = numbers.stream() </code>     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.filter(n -> n % 2 == 0) </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.map(n -> n * 2) </span>
     <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"><strong>Parallel stream:</strong></p>



<pre class="wp-block-code"><code>java

<code>// Czas: ~10ms (na multi-core!) </code>
<code>List&lt;Integer> result = numbers.parallelStream() </code>      <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.filter(n -> n % 2 == 0) </span>
      <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.map(n -> n * 2) </span>
      <span style="background-color: initial; color: rgb(240, 80, 110); font-family: inherit; font-size: 0.875rem; text-align: initial;">.collect(Collectors.toList());</span></code></pre>



<p class="wp-block-paragraph"><strong>Wnioski:</strong></p>



<ul class="wp-block-list">
<li>For pętla najszybsza dla prostych operacji</li>



<li>Stream ~30-50% wolniejszy (ogólnie)</li>



<li>Parallel stream może być najszybszy (jeśli CPU ma wiele rdzeni)</li>
</ul>



<p class="wp-block-paragraph"><strong>Ale:</strong> Różnica 10ms vs 25ms? W 99% aplikacji nieistotna. <strong>Czytelność &gt; Performance</strong> (chyba że przetwarzasz miliony rekordów).</p>



<h2 class="wp-block-heading">Co dalej &#8211; moja droga nauki</h2>



<p class="wp-block-paragraph">Po 17 tygodniach z Java (podstawy Zajavka + zaawansowane tematy):</p>



<p class="wp-block-paragraph"><strong>Decydowałam się:</strong> <strong>JavaScript!</strong></p>



<p class="wp-block-paragraph"><strong>Dlaczego nie Spring/zaawansowana Java:</strong></p>



<ul class="wp-block-list">
<li>Za ciężkie przy dzieciach i freelancingu</li>



<li>Potrzebuję czegoś bardziej natychmiast przydatnego</li>
</ul>



<p class="wp-block-paragraph"><strong>Dlaczego JavaScript:</strong></p>



<ul class="wp-block-list">
<li>Synergia z WordPress (mogę od razu stosować!)</li>



<li>Frontend umiejętności są rynkowe</li>



<li>Łatwiejszy balans życie/nauka</li>
</ul>



<p class="wp-block-paragraph"><strong>Ale Java była nieoceniona:</strong></p>



<ul class="wp-block-list">
<li>Nauczyła mnie OOP solidnie</li>



<li>Pokazała, że mogę uczyć się programowania</li>



<li>Dała fundamenty które pomogą w JS</li>
</ul>



<p class="wp-block-paragraph"><strong>Next:</strong> Learning Log #5 będzie o&#8230; JavaScript! Od Javy do JS &#8211; co jest podobne, co inne, pierwsze wrażenia.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Podsumowanie &#8211; tydzień 13-14</h2>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Nauczyłam się:</strong> Lambdy, Streams API, Optional, method references <br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Napisałam:</strong> TherapyAnalyzer &#8211; realny użytek streams <br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Zrozumiałam:</strong> Kiedy programowanie funkcyjne, kiedy imperative <br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Odkryłam:</strong> Parallel streams (game changer dla dużych zbiorów!) <br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Czas nauki:</strong> 12h w ciągu 2 tygodni (poprawiła się regularność!)</p>



<p class="wp-block-paragraph"><strong>Programowanie funkcyjne w Java początkowo:</strong> Hieroglify <br><strong>Programowanie funkcyjne w Java teraz:</strong> Potężne narzędzie które skraca kod 3x</p>



<p class="wp-block-paragraph"><strong>Czy było warto?</strong> Absolutnie. Stream API to must-know dla każdego Java developera.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>PS: Też uczysz się Java? Streams wydają Ci się trudne czy intuicyjne? A może przechodzisz z Javy na inny język? Zostaw komentarz &#8211; ciekawa jestem Waszych doświadczeń!</em></p>



<p class="wp-block-paragraph"></p>
<p>Artykuł <a href="https://www.danuta-cybulska.com/programowanie-funkcyjne-java/">Learning Log #4: Strumienie, lambdy i funkcyjne programowanie w Java</a> pochodzi z serwisu <a href="https://www.danuta-cybulska.com">To co najważniejsze</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.danuta-cybulska.com/programowanie-funkcyjne-java/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
