<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Suaki</title>
    <description>The latest articles on DEV Community by Gabriel Suaki (@gsuaki).</description>
    <link>https://dev.to/gsuaki</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F461732%2F42b98155-bf15-4ae9-a624-f3001acd79c0.png</url>
      <title>DEV Community: Gabriel Suaki</title>
      <link>https://dev.to/gsuaki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gsuaki"/>
    <language>en</language>
    <item>
      <title>Java 15 se tornou GA!</title>
      <dc:creator>Gabriel Suaki</dc:creator>
      <pubDate>Wed, 16 Sep 2020 16:04:43 +0000</pubDate>
      <link>https://dev.to/gsuaki/java-15-se-tornou-ga-4l01</link>
      <guid>https://dev.to/gsuaki/java-15-se-tornou-ga-4l01</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F72mn1ligs5y9yy2459ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F72mn1ligs5y9yy2459ie.png" alt="Cover image - Java 15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15/09/20 - Java 15 se torna GA. &lt;/p&gt;

&lt;p&gt;Além das &lt;em&gt;preview features&lt;/em&gt;, conhecidas das versões anteriores (&lt;em&gt;Text Blocks&lt;/em&gt;, &lt;em&gt;Pattern Matching&lt;/em&gt; para &lt;em&gt;instanceof&lt;/em&gt; e &lt;em&gt;Records&lt;/em&gt;), foi introduzido no Java 15 os conceitos de &lt;em&gt;sealed classes&lt;/em&gt; e &lt;em&gt;Local interfaces &amp;amp; enums&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Getting Started
&lt;/h2&gt;

&lt;p&gt;Para começar vamos instalar a &lt;em&gt;JDK&lt;/em&gt; 15. Eu utilizo o &lt;a href="https://sdkman.io/" rel="noopener noreferrer"&gt;sdkman&lt;/a&gt; para gerenciar todas as &lt;em&gt;JDKs&lt;/em&gt; do meu &lt;em&gt;workspace&lt;/em&gt;, mas se achar mais conveniente  baixar direto da OpenJDK, &lt;a href="https://jdk.java.net/15/" rel="noopener noreferrer"&gt;este é o link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Utilizando o &lt;em&gt;sdkman&lt;/em&gt;, primeiro listamos as &lt;em&gt;JDKs&lt;/em&gt; disponíveis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdk list java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fii8mrbjjuebkg1z9r6ha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fii8mrbjjuebkg1z9r6ha.png" alt="sdk list java result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, basta executar o comando com o &lt;em&gt;identifier&lt;/em&gt; encontrado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdk &lt;span class="nb"&gt;install &lt;/span&gt;java 15.ea.36-open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto! A JDK está instalada e pronta para ser usada. Agora basta configurar o IntelliJ:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjw9b6f20zznlugnvh02t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjw9b6f20zznlugnvh02t.png" alt="IntelliJ config"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;em&gt;Sealed Classes &amp;amp; Interfaces (Preview)&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Essa funcionalidade permite assumir o controle da hierarquia de classes e interfaces através da keyword &lt;code&gt;sealed&lt;/code&gt; e &lt;code&gt;permits&lt;/code&gt;. Vamos ao exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Diamond&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima, definimos a interface &lt;code&gt;Shape&lt;/code&gt; e marcamos como &lt;code&gt;sealed&lt;/code&gt;. Classes &lt;em&gt;sealed&lt;/em&gt; demandam a declaração da &lt;em&gt;keyword&lt;/em&gt; &lt;code&gt;permits&lt;/code&gt; para dizer ao compilador quais as classes ou interfaces poderão estender ou implementar &lt;code&gt;Shape&lt;/code&gt;. Existe uma exceção a regra somente para casos onde as implementações estão no mesmo arquivo que a &lt;em&gt;sealed class&lt;/em&gt;. Quando isto ocorre, podemos omitir a &lt;em&gt;keyword&lt;/em&gt; &lt;code&gt;permits&lt;/code&gt; da declaração da &lt;em&gt;sealed class&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Classes cuja classe pai é &lt;em&gt;sealed&lt;/em&gt; demandam declarar sua abrangência de hierarquia entre: &lt;code&gt;final&lt;/code&gt;, &lt;code&gt;non-sealed&lt;/code&gt; ou &lt;code&gt;sealed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Normalmente, as &lt;strong&gt;classes&lt;/strong&gt; filhas serão &lt;em&gt;final&lt;/em&gt; para evitar que possam ser herdadas. Ao tentar herdar, observará um erro de compilação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimesSquare&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Compilador fica chateado, pois Square é final.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também é possível substituir o uso da &lt;em&gt;final class&lt;/em&gt; por &lt;code&gt;record&lt;/code&gt;, pois são classes imutáveis e, por baixo dos panos, o compilador gera um &lt;em&gt;final class&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Square&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As estruturas filhas declaradas como &lt;code&gt;non-sealed&lt;/code&gt; expandem a hierarquia, possibilitando-as de serem estendidas ou implementadas por qualquer outra classe ou interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Diamond&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BigCircle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ColoredDiamond&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Diamond&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Deve-se atentar que &lt;em&gt;non-sealed classes&lt;/em&gt; podem quebrar a coesão de seus modelos, pois voltam a expor tudo o que tentou proteger com &lt;code&gt;sealed&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por último, e não menos importante, podemos ter &lt;em&gt;sealed classes&lt;/em&gt; implementando &lt;em&gt;sealed classes&lt;/em&gt;. Dessa forma, não deixamos tão aberto quanto as &lt;code&gt;non-sealed&lt;/code&gt; e nem tão engessado quanto as &lt;code&gt;final&lt;/code&gt;, continuamos restringindo a herança ou composição.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;CustomRectangle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomRectangle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.1. Type-Test Pattern matching
&lt;/h3&gt;

&lt;p&gt;Com o controle de hierarquia que as &lt;em&gt;sealed classes&lt;/em&gt; proveem ao compilador, seria possível fazer &lt;em&gt;type-test-pattern&lt;/em&gt; igual ao que vemos no &lt;a href="https://kotlinlang.org/docs/reference/control-flow.html#when-expression" rel="noopener noreferrer"&gt;&lt;em&gt;when&lt;/em&gt; do &lt;em&gt;Kotlin&lt;/em&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="nf"&gt;getAreaOfShape&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;circleArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Diamond&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;diamondArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rectangleArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;squareArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atualmente esse código acima &lt;strong&gt;não compila&lt;/strong&gt;, pois &lt;em&gt;type-test-pattern&lt;/em&gt; no &lt;em&gt;switch-case&lt;/em&gt; não é uma funcionalidade ainda, é apenas uma possibilidade. A razão disso, é por conta do precedente que foi adicionado ao Java 14: &lt;em&gt;Pattern Matching for instanceof&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Indo mais além, pelo fato do compilador saber exatamente quem implementa determinada &lt;em&gt;sealed class&lt;/em&gt;, seria possível omitir o &lt;em&gt;default&lt;/em&gt; no &lt;em&gt;switch-case&lt;/em&gt;, pois todas as possibilidades foram declaradas.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Local interfaces e enums
&lt;/h2&gt;

&lt;p&gt;Com a segunda &lt;em&gt;preview&lt;/em&gt; de &lt;em&gt;Records&lt;/em&gt; (&lt;a href="https://openjdk.java.net/jeps/384" rel="noopener noreferrer"&gt;JEP 384&lt;/a&gt;) assomado no Java 15, a possibilidade de criar estruturas no escopo local de um método virou realidade. Além das &lt;em&gt;records&lt;/em&gt;, agora podemos declarar classes, &lt;em&gt;enums&lt;/em&gt; e interfaces dentro do escopo de métodos também!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;TV&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getTop5ExpensiveTV&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;TV&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tvs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Price&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;EXPENSIVE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CHEAP&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;TVPrice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;TV&lt;/span&gt; &lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 

      &lt;span class="nc"&gt;Price&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4_000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;Price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EXPENSIVE&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHEAP&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tvs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TVPrice&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculateAmount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sorted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;comparing&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;TVPrice:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;TVPrice:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O exemplo acima mostra uma forma de usufruir de estruturas locais. Foi utilizado &lt;em&gt;local&lt;/em&gt; &lt;code&gt;record&lt;/code&gt; e &lt;code&gt;enum&lt;/code&gt; para fazer um filtro em uma lista.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. What’s next?
&lt;/h2&gt;

&lt;p&gt;Existem outras &lt;em&gt;features&lt;/em&gt; de melhoria de performance e reimplementações de estruturas, não hesite em ler o &lt;a href="https://openjdk.java.net/projects/jdk/15/" rel="noopener noreferrer"&gt;&lt;em&gt;release notes&lt;/em&gt; completo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://openjdk.java.net/projects/jdk/15/" rel="noopener noreferrer"&gt;JDK 15&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jetbrains.com/idea/2020/09/java-15-and-intellij-idea/" rel="noopener noreferrer"&gt;Java 15 and IntelliJ IDEA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kotlinlang.org/docs/reference/control-flow.html#when-expression" rel="noopener noreferrer"&gt;Kotlin docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>record</category>
      <category>java15</category>
      <category>sealed</category>
    </item>
    <item>
      <title>Programação Funcional em Java #2 - Descomplicando o Vavr</title>
      <dc:creator>Gabriel Suaki</dc:creator>
      <pubDate>Thu, 10 Sep 2020 11:35:36 +0000</pubDate>
      <link>https://dev.to/gsuaki/programacao-funcional-em-java-2-desmistificando-o-vavr-53c3</link>
      <guid>https://dev.to/gsuaki/programacao-funcional-em-java-2-desmistificando-o-vavr-53c3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EItH91In--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jb0egzsi35sscn9yhtfo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EItH91In--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jb0egzsi35sscn9yhtfo.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Descomplicando o Vavr
&lt;/h1&gt;

&lt;p&gt;Se você está se perguntando "Qual a relação entre Programação Funcional e &lt;em&gt;Vavr&lt;/em&gt; ?" não se preocupe, vou te explicar. A biblioteca &lt;em&gt;Vavr&lt;/em&gt; é um &lt;em&gt;superset&lt;/em&gt; de construções básicas que linguagens funcionais oferecem por padrão, com exceção do Java - o que dificulta a utilização do paradigma funcional no dia-a-dia.&lt;/p&gt;

&lt;p&gt;A biblioteca conta com várias construções e aqui focaremos nas mais importantes: &lt;em&gt;Functions&lt;/em&gt;, &lt;em&gt;Monads&lt;/em&gt;, &lt;em&gt;Collections&lt;/em&gt; e &lt;em&gt;Pattern Matching&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Functions
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Functions&lt;/em&gt; enriquece as funções de uma maneira jamais vista antes no Java. É considerado um dos pilares mais importantes, pois Programação Funcional é sobre valores e como manipulá-los  através de funções. Esse módulo sobre funções é divido em cinco conceitos: &lt;em&gt;Composition&lt;/em&gt;, &lt;em&gt;Lifting&lt;/em&gt;, &lt;em&gt;Partial application&lt;/em&gt;, &lt;em&gt;Currying&lt;/em&gt; e &lt;em&gt;Memoization&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1. Composition
&lt;/h3&gt;

&lt;p&gt;Esse é o conceito mais simples (também encontramos nas interfaces do Java). É basicamente sobre compor as funções a fim de obter maior robustez e significância. Veja o exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andThen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Líquido de 900&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo acima definimos três funções. A primeira &lt;code&gt;tributoIRRF&lt;/code&gt; recebe um inteiro e subtrai 1000. A segunda &lt;code&gt;contribuicaoINSS&lt;/code&gt; também recebe um inteiro mas subtrai apenas 100. Na terceira função &lt;code&gt;calculaSalarioLiquido&lt;/code&gt; não implementamos nenhuma lógica, ao invés disso foi feita uma composição entre as duas primeiras funções. Ao executar &lt;code&gt;calculaSalarioLiquido&lt;/code&gt; seguimos a lógica em invocar  &lt;code&gt;tributoIRRF&lt;/code&gt; e, então, invocar &lt;code&gt;contribuicaoINSS&lt;/code&gt;. Convertendo para funções matemáticas, podemos ler &lt;code&gt;f(x): ((x - 1000) - 100)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Além do &lt;code&gt;andThen&lt;/code&gt;, também é possível alterar a ordem da execução com o &lt;code&gt;compose&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compose&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Líquido de 900&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, o resultado obtido ainda é o mesmo, mas agora lê-se &lt;code&gt;f(x): ((x - 100) - 1000)&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2. Lifting
&lt;/h3&gt;

&lt;p&gt;Esse conceito consiste em envolver uma função que consideramos parcial gerando uma função total. Para entender melhor, veja este exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;calculaImposto&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tributoIRRF&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Imposto não pode ser menor que 0"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse método &lt;code&gt;calculaImposto&lt;/code&gt; retorna a soma entre os dois impostos da entrada, caso sejam maiores que 0, do contrário, lança uma exceção. O fato de lançar tal exceção o torna uma função parcial. Podemos tornar a mesma completa utilizando o &lt;code&gt;Function2.lift&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Function2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculadorDeImposto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="nc"&gt;Function2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lift&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;calculaImposto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Epa! &lt;code&gt;Option&lt;/code&gt;, &lt;em&gt;what!?&lt;/em&gt; Calma, por ora, o que você precisa saber é que este &lt;code&gt;Option&lt;/code&gt; tem a semântica do &lt;code&gt;Optional&lt;/code&gt; do Java e tem duas representações: &lt;code&gt;None()&lt;/code&gt; quando é vazio e &lt;code&gt;Some(n)&lt;/code&gt; quando há um valor. &lt;/p&gt;

&lt;p&gt;Voltando ao exemplo, na nova função &lt;code&gt;calculadorDeImposto&lt;/code&gt;, agora indicamos ao consumidor que a função pode ou não produzir um resultado. No caso, se o valor de um dos impostos for menor que zero e o método principal &lt;code&gt;calculaImposto&lt;/code&gt; lançar uma exceção, o resultado da operação é &lt;code&gt;None()&lt;/code&gt;. Por outro lado, caso os parâmetros estiverem OK, o resultado é &lt;code&gt;Some(n)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3. Partial application
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Partial application&lt;/em&gt; consiste em reduzir gradativamente a quantidade de parâmetros de uma função aplicando aqueles que estão disponíveis. É parecido com o conceito &lt;code&gt;Currying&lt;/code&gt;, mas não se engane, pois eles são diferentes. Vamos ao exemplo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 1. Reduzindo parâmetros até o último&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salario&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salarioBruto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salarioMenosIRRF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioBruto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioMenosIRRF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo 1, a função &lt;code&gt;calculaSalarioLiquido&lt;/code&gt; é de aridade três, ou seja, demanda três parâmetros de entrada. Supondo que no momento da execução não temos todos os três valores, como proceder? Felizmente, o &lt;em&gt;Vavr&lt;/em&gt; está preparado para receber os valores individualmente e ir reduzindo a aridade da função, exatamente como no exemplo 1. &lt;/p&gt;

&lt;p&gt;Primeiramente aplicamos o valor do salário (2000) e a função &lt;code&gt;calculaSalarioLiquido&lt;/code&gt; nos retornou uma &lt;strong&gt;nova função&lt;/strong&gt; de aridade dois, a qual chamamos de &lt;code&gt;salarioBruto&lt;/code&gt;. Em seguida, aplicamos o próximo valor (1000) referente ao &lt;strong&gt;tributoIRRF&lt;/strong&gt; e o resultado foi uma &lt;strong&gt;nova função&lt;/strong&gt; de aridade um, a qual chamamos de &lt;code&gt;salarioMenosIRRF&lt;/code&gt;. Por fim, aplicamos o valor de 100 referente a &lt;strong&gt;contribuicaoINSS&lt;/strong&gt; e obtivemos o resultado final que é o salário líquido no valor de 900.&lt;/p&gt;

&lt;p&gt;O &lt;em&gt;Vavr&lt;/em&gt; também possibilita fazer de outras formas. No próximo exemplo utilizamos os métodos &lt;code&gt;reversed()&lt;/code&gt; e &lt;code&gt;.apply(p1, p2)&lt;/code&gt; de aridade dois, veja:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 2. Invertendo a ordem e aplicando dois parâmetros de uma só vez&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salario&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salarioMenosIRRFeINSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reversed&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioMenosIRRFeINSS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse segundo cenário fizemos basicamente a &lt;strong&gt;inversão&lt;/strong&gt; dos parâmetros de entrada para que pudéssemos aplicar os dois impostos de uma só vez e, então, gerar função &lt;code&gt;salarioMenosIRRFeINSS&lt;/code&gt; cuja aridade caiu de três para um. Dessa forma, para o cálculo da aridade da função resultante utilizamos a fórmula: &lt;code&gt;aridade original - parâmetros aplicados&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4. Currying
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Currying&lt;/em&gt; é a técnica de quebrar a aridade de uma função em funções de aridade única. Ficou confuso? Vamos ao exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salario&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculoSeparado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;curried&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, podemos ver nossa conhecida função, de aridade três e bastante complexa, &lt;code&gt;calculaSalarioLiquido&lt;/code&gt;. Com o uso do &lt;code&gt;.curried()&lt;/code&gt; possibilitamos desmembrá-la em três funções encadeadas de um único parâmetro.&lt;/p&gt;

&lt;p&gt;Para invocar a função resultante de &lt;code&gt;.curried()&lt;/code&gt;, faremos desta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculoSeparado&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resumindo, a diferença entre &lt;em&gt;Currying&lt;/em&gt; e &lt;em&gt;Partial application&lt;/em&gt; é que &lt;em&gt;Currying&lt;/em&gt; quebra a função em funções de aridade única encadeadas, enquanto o &lt;em&gt;Partial application&lt;/em&gt; é flexível, pois resulta sempre em uma função com o restante dos parâmetros não aplicados.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.5. Memoization
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Memoization&lt;/em&gt; consiste em cachear o resultado de uma função com base nos parâmetros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salario&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contribuicaoINSS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tributoIRRF&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Function1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salarioMenosDescontos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;calculaSalarioLiquido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reversed&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;memoized&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioMenosDescontos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Calcula e cacheia&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioMenosDescontos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Utiliza valor do cache&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;salarioLiquido3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salarioMenosDescontos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Calcula e cacheia&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supondo que &lt;code&gt;calculaSalarioLiquido&lt;/code&gt; demande uma computação enorme e que os parâmetros &lt;code&gt;tributoIRRF&lt;/code&gt; e &lt;code&gt;contribuicaoINSS&lt;/code&gt; não se alterem com muita frequência, podemos aplicar os parâmetros de impostos e marcar a função resultante como &lt;code&gt;.memoized()&lt;/code&gt;, assim, a &lt;strong&gt;nova função&lt;/strong&gt; &lt;code&gt;salarioMenosDescontos&lt;/code&gt; terá o comportamento de cachear o resultado em memória, sendo a chave o parâmetro de entrada. Ou seja, ao aplicar o valor 2000, toda computação é feita e ao final armazena-se o resultado. Se o valor for &lt;em&gt;inputado&lt;/em&gt; novamente o cache estará populado, retornando o resultado computado previamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1. Monads
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Monads&lt;/em&gt; são &lt;em&gt;typeclasses&lt;/em&gt; que encapsulam um &lt;strong&gt;valor&lt;/strong&gt; a um comportamento específico. Você conhece o &lt;code&gt;java.util.Optional&lt;/code&gt; ? É um &lt;em&gt;Monad&lt;/em&gt;. Ele encapsula um &lt;strong&gt;valor&lt;/strong&gt; que pode, ou não, estar presente.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Option
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Option&lt;/em&gt; é um container que representa um valor opcional. Por baixo dos panos, a interface &lt;em&gt;Option&lt;/em&gt; tem duas implementações: &lt;code&gt;Some(value)&lt;/code&gt; quando há valor dentro do &lt;em&gt;Option&lt;/em&gt; e &lt;code&gt;None()&lt;/code&gt; para quando não há.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maybeName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Some(string)&lt;/span&gt;

&lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maybeName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// None()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja que, diferentemente do &lt;code&gt;Optional&lt;/code&gt;, o &lt;em&gt;factory method&lt;/em&gt; padrão do &lt;code&gt;Option&lt;/code&gt; contém a inteligência de fazer a triagem do valor &lt;em&gt;null&lt;/em&gt;, sem precisar de um outro método como &lt;code&gt;Optional.ofNullable&lt;/code&gt;. Além disso, existe outra diferença muito importante no comportamento do &lt;code&gt;.map&lt;/code&gt; que ,se você não se atentar, pode resultar em NPEs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 1. &lt;em&gt;Optional&lt;/em&gt; padrão do Java&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gabriel"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// (2)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// (3) Não acontece&lt;/span&gt;

&lt;span class="n"&gt;assertFalse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPresent&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Optional com valor interno "gabriel".&lt;/li&gt;
&lt;li&gt;Optional se torna vazio pois &lt;em&gt;null&lt;/em&gt; é retornado.&lt;/li&gt;
&lt;li&gt;Não é invocado pois o Optional está vazio.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No exemplo acima, ao retornar &lt;em&gt;null&lt;/em&gt; no primeiro &lt;code&gt;.map&lt;/code&gt;, podemos observar que o comportamento é de desconsiderar os próximos &lt;code&gt;.map&lt;/code&gt;, pois o valor interno tornou-se vazio. Caso prosseguisse para o próximo &lt;code&gt;.map(value -&amp;gt; value.toLowerCase())&lt;/code&gt; o resultado seria, inevitavelmete, NPE, já que &lt;em&gt;value&lt;/em&gt; passou a ser &lt;em&gt;null&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 2. &lt;em&gt;Option&lt;/em&gt; do *Vavr&lt;/strong&gt;*&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gabriel"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// (3) throws NullPointerException&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Option com valor interno &lt;code&gt;Some("gabriel")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Option se torna &lt;code&gt;Some(null)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.map&lt;/code&gt; é invocado com valor &lt;em&gt;null&lt;/em&gt; e um NPE é lançado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simulando o mesmo cenário, mas com &lt;em&gt;Option&lt;/em&gt; do &lt;em&gt;Vavr&lt;/em&gt;, observamos que &lt;em&gt;NullPointerException&lt;/em&gt; é lançado ao tentar invocar &lt;code&gt;.toLowerCase&lt;/code&gt; em uma variável &lt;em&gt;null&lt;/em&gt;. Isso acontece porque a semântica do &lt;code&gt;.map&lt;/code&gt; do &lt;em&gt;Vavr&lt;/em&gt; preserva o conceito matemático de que invocar &lt;code&gt;.map&lt;/code&gt; em um &lt;code&gt;Some&lt;/code&gt; resulta em outro &lt;code&gt;Some&lt;/code&gt;, e invocar &lt;code&gt;.map&lt;/code&gt; em um &lt;code&gt;None&lt;/code&gt; resulta em outro &lt;code&gt;None&lt;/code&gt;. No &lt;code&gt;Optional&lt;/code&gt; do Java, o resultado &lt;em&gt;null&lt;/em&gt; ao invocar o &lt;code&gt;.map&lt;/code&gt; altera o contexto interno de &lt;code&gt;Some&lt;/code&gt; para &lt;code&gt;None&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Sabendo disso, o que fazer para voltar a estar seguro contra &lt;em&gt;null&lt;/em&gt; ? É simples. Ao invés de &lt;code&gt;.map&lt;/code&gt;, &lt;strong&gt;flatMap that shit!&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gabriel"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// we are safe&lt;/span&gt;

&lt;span class="n"&gt;assertFalse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPresent&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para conhecer mais sobre o assunto, recomendo este &lt;em&gt;post&lt;/em&gt; &lt;a href="http://blog.vavr.io/the-agonizing-death-of-an-astronaut"&gt;The agonizing death of an astronaut&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2. Try
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Try&lt;/em&gt; é um container que representa uma execução que pode resultar em sucesso ou em uma exceção.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simples try com valor padrão em caso de erro.&lt;/span&gt;
&lt;span class="nc"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculaImpostos&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valorDefault&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Exemplo um pouco mais avançado utilizando Try with resources para ler um InputStream&lt;/span&gt;
&lt;span class="nc"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withResources&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readFile&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;IOUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em caso de erro, esse mônada fornece métodos utilitários que nos permite fazer tratamentos, tais como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;calculaImposto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recover&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recover&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromB&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recoverWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromC&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou, podemos utilizar &lt;em&gt;Pattern Matching&lt;/em&gt; - conceito que veremos mais à frente - e unificar os &lt;code&gt;.recover&lt;/code&gt; com &lt;em&gt;rebuscado fancy&lt;/em&gt; &lt;em&gt;switch-case&lt;/em&gt; funcional &lt;em&gt;Match&lt;/em&gt;, fornecido pelo &lt;em&gt;Vavr&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;calculaImposto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recover&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
     &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instanceOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
     &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instanceOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromB&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
     &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instanceOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromC&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
     &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;recoverFromUnknown&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;impostoPadrao&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, fica  notável como &lt;em&gt;Vavr&lt;/em&gt; nos permite desenvolver códigos &lt;strong&gt;funcionais&lt;/strong&gt; e &lt;strong&gt;expressivos&lt;/strong&gt;. Além dos métodos exemplificados, &lt;em&gt;Try&lt;/em&gt; conta com hooks como &lt;code&gt;.onFailure&lt;/code&gt;, &lt;code&gt;.onSuccess&lt;/code&gt;, &lt;code&gt;.andFinally&lt;/code&gt;, &lt;code&gt;.andThen&lt;/code&gt;, entre outros.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3. Lazy
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Lazy&lt;/em&gt; é um container que representa um valor que não precisa ser computado no momento em que é criado, apenas quando solicitado. Diferentemente do &lt;em&gt;Supplier&lt;/em&gt;, cuja semântica é parecida, no &lt;em&gt;Lazy&lt;/em&gt; o resultado é cacheado ao ser evaluado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Lazy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Lazy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;UUID:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEvaluated&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (2)&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;newID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (3)&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEvaluated&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (4)&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;cachedID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (5)&lt;/span&gt;
&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newID&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cachedID&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Cria-se instância do &lt;em&gt;Lazy&lt;/em&gt; a partir de um &lt;em&gt;supplier&lt;/em&gt; de &lt;em&gt;UUID&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isEvaluated&lt;/code&gt; é &lt;em&gt;false&lt;/em&gt; por não ter sido invocado o &lt;code&gt;.get&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Invoca-se o &lt;code&gt;.get&lt;/code&gt; que invoca o &lt;em&gt;supplier&lt;/em&gt; &lt;code&gt;UUID.randomUUID&lt;/code&gt; gerando o &lt;em&gt;UUID&lt;/em&gt; aleatório.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isEvaluated&lt;/code&gt; passa a ser &lt;em&gt;true&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Invoca-se o &lt;code&gt;.get&lt;/code&gt; e retorna o UUID cacheado do &lt;strong&gt;passo 3&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Outra funcionalidade muito interessante é o suporte a &lt;em&gt;interfaces&lt;/em&gt;, onde a instância da implementação é feita via &lt;em&gt;Proxy&lt;/em&gt; na primeira chamada de qualquer método da &lt;em&gt;interface&lt;/em&gt;. Não entendeu ? Vamos ao exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraImposto&lt;/span&gt; &lt;span class="n"&gt;inss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Lazy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;val&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;CalculadoraINSS:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraImposto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;inss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcular&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
&lt;span class="n"&gt;inss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calcular&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// (2)&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraImposto&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;calcular&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraINSS&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraImposto&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CalculadoraINSS&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Instanciando calculadora INSS"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Computação custosa e demorada&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;calcula&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Invoca-se o método &lt;code&gt;calcular&lt;/code&gt;, o qual passa pelo &lt;em&gt;proxy&lt;/em&gt; e invoca o &lt;em&gt;supplier&lt;/em&gt; &lt;code&gt;CalculadoraINSS::new&lt;/code&gt;, cacheando o resultado e depois invocando o método.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invoca-se o método &lt;code&gt;calcular&lt;/code&gt;, o qual também passa pelo &lt;em&gt;proxy&lt;/em&gt;, mas desta vez, o resultado do &lt;em&gt;supplier&lt;/em&gt; está cacheado e não passa pelo &lt;code&gt;CalculadoraINSS::new&lt;/code&gt;, indo direto ao método.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nesse exemplo, temos a &lt;em&gt;interface&lt;/em&gt; &lt;code&gt;CalculadoraImposto&lt;/code&gt; e a implementação &lt;code&gt;CalculadoraINSS&lt;/code&gt;. Supondo que instanciar &lt;code&gt;CalculadoraINSS&lt;/code&gt; demande muito poder computacional e &lt;em&gt;tempo&lt;/em&gt;, obviamente não gostaríamos de instanciar sem realmente precisar. Utilizando &lt;em&gt;factory method&lt;/em&gt; &lt;code&gt;Lazy.val&lt;/code&gt;, passamos como primeiro parâmetro o &lt;em&gt;Supplier&lt;/em&gt;, responsável por construir o objeto, e como segundo parâmetro o &lt;code&gt;.class&lt;/code&gt; da interface, a qual a implementação pertence (CalculadoraImposto). Repare que o retorno do &lt;code&gt;Lazy.val&lt;/code&gt; é a própria interface e não &lt;code&gt;Lazy&amp;lt;CalculadoraImposto&amp;gt;&lt;/code&gt;, como no exemplo anterior com &lt;code&gt;Lazy.of&lt;/code&gt;. O truque aqui é que o &lt;em&gt;Vavr&lt;/em&gt; cria um &lt;em&gt;Proxy&lt;/em&gt; dinâmico da interface envolvendo o &lt;em&gt;Supplier&lt;/em&gt; em um &lt;em&gt;Lazy&lt;/em&gt;. Quando qualquer invocação é feita, nos métodos da interface, primeiro passa-se pelo &lt;em&gt;Proxy&lt;/em&gt; que invoca o &lt;code&gt;Lazy.get&lt;/code&gt; e depois invoca-se a implementação real do método, caso necessário. Como vimos acima, &lt;code&gt;Lazy.get&lt;/code&gt; faz cache do resultado, ou seja, só invocamos o construtor &lt;code&gt;CalculadoraINSS&lt;/code&gt; uma vez e a instância fica em memória para ser reutilizada.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4. Either
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Either&lt;/em&gt; é um container que representa um valor que pode se apresentar de duas maneiras diferentes. Por debaixo dos panos, a interface &lt;em&gt;Either&lt;/em&gt; tem duas implementações: &lt;code&gt;Left()&lt;/code&gt;  e &lt;code&gt;Right()&lt;/code&gt; .&lt;br&gt;
Este mônada é bastante utilizada para representar um valor que deu certo (&lt;em&gt;right&lt;/em&gt;) ou que falhou (&lt;em&gt;left&lt;/em&gt;). Imagino que você esteja se perguntando  "qual a diferença entre &lt;em&gt;Either&lt;/em&gt; e &lt;em&gt;Try&lt;/em&gt;" ? Bom, assim como o &lt;em&gt;Either&lt;/em&gt;, a semântica do &lt;em&gt;Try&lt;/em&gt; também  representa um valor que pode ser um sucesso ou um erro. A grosso modo, é possível visualizar o &lt;em&gt;Try&lt;/em&gt; sendo um &lt;code&gt;Either&amp;lt;Throwable, R&amp;gt;&lt;/code&gt;, todavia, seu contexto é inteiro voltado para isso e &lt;strong&gt;apenas&lt;/strong&gt; isso. Por outro lado, o &lt;em&gt;Either&lt;/em&gt; é flexível e não representa, necessariamente, sucesso ou falha.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;impostoINSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculaINSS&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;inss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;impostoINSS&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imposto&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;imposto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrElseThrow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// (2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;.map&lt;/code&gt; só será executado caso o &lt;em&gt;Either&lt;/em&gt; seja &lt;em&gt;Right&lt;/em&gt;, ou seja, sucesso.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Caso seja &lt;em&gt;Left&lt;/em&gt;, lidamos com erro invocando &lt;code&gt;handleError&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No exemplo acima, &lt;em&gt;Either&lt;/em&gt; foi utilizado para indicar cálculo do INSS com sucesso (&lt;em&gt;right&lt;/em&gt;) ou falha (&lt;em&gt;left&lt;/em&gt;). &lt;code&gt;calculaINSS&lt;/code&gt; poderia retornar &lt;em&gt;Try&lt;/em&gt; ao invés de &lt;em&gt;Either&lt;/em&gt; ? Sim, mas repare que a assinatura é &lt;code&gt;Either&amp;lt;String, Integer&amp;gt;&lt;/code&gt;, se fosse &lt;em&gt;Try&lt;/em&gt; lidaríamos com &lt;code&gt;Throwable&lt;/code&gt; ao invés de &lt;code&gt;String&lt;/code&gt;, o que pode fazer toda diferença para o contexto da aplicação e a maneira como lidamos com a falha.&lt;br&gt;
Existem outras formas de trabalhar com o &lt;em&gt;Either&lt;/em&gt;, conheça o &lt;code&gt;.fold&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;inss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;impostoINSS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fold&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// (1) &lt;/span&gt;
  &lt;span class="n"&gt;imposto&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;salario&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;imposto&lt;/span&gt; &lt;span class="c1"&gt;// (2)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ignora-se a mensagem de erro &lt;em&gt;left&lt;/em&gt; e retorna o valor padrão 1000. Poderíamos obter o mesmo resultado alterando a implementação do &lt;code&gt;leftMapper&lt;/code&gt; por &lt;code&gt;left -&amp;gt; { throw handleError(left); }&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mantém o mesmo comportamento que o exemplo anterior para caso de sucesso.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Diferentemente do &lt;code&gt;.map&lt;/code&gt; e &lt;code&gt;.getOrElseThrow&lt;/code&gt; encadeados, o &lt;code&gt;.fold&lt;/code&gt; recebe ambos os &lt;em&gt;mappers&lt;/em&gt; (&lt;em&gt;leftMapper&lt;/em&gt; e &lt;em&gt;rightMapper&lt;/em&gt;) e utiliza um deles dependendo de seu estado interno (&lt;em&gt;left&lt;/em&gt; ou &lt;em&gt;right&lt;/em&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  3 Collections
&lt;/h2&gt;

&lt;p&gt;As coleções do &lt;em&gt;Vavr&lt;/em&gt; são uma evolução das que encontramos no Java. Todas são imutáveis e cada tentativa de mutação gera uma nova lista, ou seja, são estruturas persistentes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 1. java.util.List vs io.vavr.collection.List&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Java 8&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;util&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;list&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ifPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Vavr - io.vavr.collection.List&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// List(1, 2, 3) &lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// List(1, 2, 3, 4)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// List(1, 2, 3, 4, 5)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// List(9, 1, 2, 3, 4, 5)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pop&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// List(9, 6, 2, 3, 4, 5)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Option(9)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;peek&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parece complexo, mas na verdade é bem simples. No exemplo acima, ambas &lt;em&gt;collections&lt;/em&gt; iniciam-se com valores de 1, 2 e 3. Em seguida, adicionam-se os inteiros 4 e 5. Depois disso, insere-se o número 9 como primeiro elemento da lista e atualiza-se o valor do elemento de índice 1 para 6. Na próxima etapa devemos ir à procura  do maior valor da lista e imprimir no console.&lt;/p&gt;

&lt;p&gt;Podemos observar que a lista do &lt;em&gt;Vavr&lt;/em&gt; é bem mais simples de se manipular. Cada manipulação gera uma nova lista e não corremos o risco de algum &lt;em&gt;side-effect&lt;/em&gt; indesejado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 2. io.vavr.collection.HashMap&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;setOfNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Joao"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Caio"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pedro"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fernando"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nameWithSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;setOfNames&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;nameWithSize&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filterValues&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeIfAbsent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Priscila"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_2&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeIfPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_2&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;maxBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_2&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;peek&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todas as coleções são otimizadas no quesito &lt;em&gt;Time Complexity&lt;/em&gt;, para saber mais: &lt;a href="https://www.vavr.io/vavr-docs/#_performance_characteristics"&gt;Performance Characteristics&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Pattern Matching
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Finalmente chegamos na parte mais poderosa do &lt;em&gt;Vavr&lt;/em&gt; - e aquela que eu mais utilizo! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Pattern Matching&lt;/em&gt; é a habilidade de comparar um valor aos padrões estipulados. Caso surja algum match, aplica-se a função correspondente ao valor. Na prática é um hiper &lt;em&gt;switch-case&lt;/em&gt;, veja o exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;vavr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;API&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;
&lt;span class="c1"&gt;// io.vavr.API.Match, io.vavr.API.Case e io.vavr.API.$&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gab"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isNull&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isIn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Monica"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Cebolinha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Joao"&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instanceOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CharSequence&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O exemplo acima é bastante simples, mas exibe as possibilidades que &lt;em&gt;Pattern Matching&lt;/em&gt; nos dá. A estrutura apresenta-se como: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Match(valor)&lt;/code&gt; entrando com valor que será comparado aos padrões.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Case(padrão, função)&lt;/code&gt; definindo o padrão que será comparado e, se servir, a função na qual será aplicado o valor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os possíveis &lt;strong&gt;padrões&lt;/strong&gt;, dentro do &lt;code&gt;Case&lt;/code&gt;, podem ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$() - Padrão genérico/default&lt;/li&gt;
&lt;li&gt;$(value) - Padrão &lt;em&gt;equals&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;$(predicate) - Padrão condicional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Caso não queira usar o padrão genérico &lt;code&gt;$()&lt;/code&gt;, é necessário utilizar o &lt;code&gt;Match().option&lt;/code&gt; ao invés de &lt;code&gt;Match().of&lt;/code&gt; e tratar manualmente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;plusOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;option&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instanceOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nc"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instanceOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. What’s next?
&lt;/h2&gt;

&lt;p&gt;A biblioteca &lt;em&gt;Vavr&lt;/em&gt; ainda tem muito mais a ser explorada, não hesite em ler a &lt;a href="https://www.vavr.io/vavr-docs"&gt;documentação completa&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vavr.io/vavr-docs/"&gt;Vavr docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.vavr.io/the-agonizing-death-of-an-astronaut/"&gt;The agonizing death of an astronaut&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learnyouahaskell.com/a-fistful-of-monads"&gt;A Fistful of Monads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arrow-kt.io/docs/patterns/monad_comprehensions/"&gt;Monad comprehensions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=pPy-ETY8a-E"&gt;Functional Exception Handling in Java with Vavr by Grzegorz Piwowarek&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>functional</category>
      <category>vavr</category>
      <category>monad</category>
    </item>
    <item>
      <title>Programação Funcional em Java #1 - Fundamentos básicos do paradigma</title>
      <dc:creator>Gabriel Suaki</dc:creator>
      <pubDate>Tue, 01 Sep 2020 19:15:07 +0000</pubDate>
      <link>https://dev.to/gsuaki/programacao-funcional-em-java-1-fundamentos-basicos-do-paradigma-3f95</link>
      <guid>https://dev.to/gsuaki/programacao-funcional-em-java-1-fundamentos-basicos-do-paradigma-3f95</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FAMi945u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wu5y3ldfgm1h04y4iog4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FAMi945u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wu5y3ldfgm1h04y4iog4.png" alt="Programação Funcional em Java"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Fundamentos básicos do paradigma + Estrutura de dados
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Fundamente-se
&lt;/h2&gt;

&lt;p&gt;É comum ouvir palpites em &lt;em&gt;Pull Requests&lt;/em&gt; como: "ei, você pode refatorar esse código usando programação funcional. Use filter, map ou reduce". Mas será que programação funcional é sobre isso? Bom, já adianto que não. O que define o paradigma funcional são suas características: Comportamento reproduzível (&lt;em&gt;Referencial transparency&lt;/em&gt;), funções puras (&lt;em&gt;The absence of side-effects&lt;/em&gt;) e valores imutáveis (&lt;em&gt;Immutability&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1. Referencial transparency
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Referencial transparency&lt;/em&gt; refere-se a substituição de uma função pelo seu valor. No código abaixo, ao substituir a função &lt;code&gt;sum&lt;/code&gt; pelo valor da soma, não há alteração no comportamento da aplicação, independente de quantas vezes é invocada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dez&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dez&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NAIL IT&lt;/span&gt;

&lt;span class="c1"&gt;// outro exemplo com Strings&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;snaked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Invoice_ID"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Invoice ID"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"_"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snaked&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NAIL IT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Já no código abaixo isso não ocorre. Não podemos prever o valor de &lt;code&gt;result&lt;/code&gt; por ser randômico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cinco&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cinco&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// FAIL IT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.2. Pure functions
&lt;/h3&gt;

&lt;p&gt;Essa característica é dividida em dois aspectos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O valor da função será sempre o mesmo para a mesma entrada. Não importa quantas vezes chamamos &lt;code&gt;Math.sum(7, 3)&lt;/code&gt;, o resultado sempre será 10. Caso a entrada mude (&lt;code&gt;Math.sum(10, 3)&lt;/code&gt;), o resultado muda também. É importante ressaltar que esse fator descarta qualquer tipo de apontamento externo ou referência mutável. Veja o exemplo abaixo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="no"&gt;NINE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;plusNine&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;NINE&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;plusNine&lt;/code&gt; parece ser pura, tendo seu valor reproduzível. Entretanto, ela aponta para uma variável estática e mutável externa à seu escopo, tornando-a impura.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sua execução não possui &lt;em&gt;side-effects&lt;/em&gt;. Comportamentos como apontar para uma variável estática, apontar para uma variável fora do escopo da função ou alterar algum estado interno (ou de um parâmetro) são qualificados como &lt;em&gt;side-effects&lt;/em&gt;. Dito isto, fica claro que funções &lt;code&gt;void&lt;/code&gt; possuem &lt;em&gt;side-effects&lt;/em&gt;, do contrário, por que invocar uma função que não produz valor ?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1.3. Immutability
&lt;/h3&gt;

&lt;p&gt;Imutabilidade é um conceito bastante conhecido porém pouco trabalhado, principalmente em linguaguem orientada a objetos. Essa característica implica em construir um objeto e não poder alterar o seu estado interno, ou seja, seu valor. No Java as classes mais utilizadas são imutáveis como, por exemplo: &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;LocalDate&lt;/code&gt;, &lt;code&gt;LocalDateTime&lt;/code&gt;, &lt;code&gt;BigInteger&lt;/code&gt;, &lt;code&gt;BigDecimal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 1. Strings&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nomeEmMinusculo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NAIL IT&lt;/span&gt;
&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gabriel"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nomeEmMinusculo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NAIL IT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exemplo 2. BigInteger&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BigInteger&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BigInteger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BigInteger&lt;/span&gt; &lt;span class="n"&gt;agePlusFive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigInteger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5L&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NAIL IT&lt;/span&gt;
&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agePlusFive&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NAIL IT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em ambos exemplos o estado interno do objeto não se alterou, tanto &lt;code&gt;BigInteger.add&lt;/code&gt; quanto &lt;code&gt;String.toLowerCase&lt;/code&gt; &lt;br&gt;
produzem o resultado esperado, porém em um novo objeto. Neste próximo exemplo, entretanto, o mesmo não se aplica:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo 3. ArrayList&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;integers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;integers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;integers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// FAIL IT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O método &lt;code&gt;List.add&lt;/code&gt; produz um &lt;code&gt;boolean&lt;/code&gt;, logo, fica evidente que altera o estado interno da lista para armazenar o novo inteiro, do contrário,&lt;code&gt;List.add&lt;/code&gt; produziria uma nova lista. Podemos dizer então que há &lt;em&gt;side-effect&lt;/em&gt; e &lt;em&gt;ArrayList&lt;/em&gt; não é imutável.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Estrutura de dados
&lt;/h2&gt;

&lt;p&gt;No paradigma Funcional não trabalhamos com classes que encapsulam comportamento e estado. Ao invés, trabalhamos com estrutura de dados as quais são divididas em três tipos: &lt;strong&gt;Estruturas mutáveis&lt;/strong&gt;, &lt;strong&gt;estruturas imutáveis&lt;/strong&gt; e &lt;strong&gt;estruturas persistêntes&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Estruturas mutáveis
&lt;/h3&gt;

&lt;p&gt;É basicamente o que vimos no &lt;code&gt;exemplo 3&lt;/code&gt;. A estrutura &lt;code&gt;ArrayList&lt;/code&gt; do Java é mutável por padrão. Toda operação altera o estado interno da estrutura.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2. Estruturas imutáveis
&lt;/h3&gt;

&lt;p&gt;Essas estruturas não se alteram pós construção e, no Java, as operações lançam erros. Veja o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;integers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;integers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// throws UnsupportedOperationException&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O método &lt;code&gt;unmodifiableList&lt;/code&gt; transforma uma lista mutável em uma nova lista imutável e, feito isso, toda tentativa de alterar o estado interno resulta no erro &lt;code&gt;UnsupportedOperationException&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3. Estruturas persistentes
&lt;/h3&gt;

&lt;p&gt;Nesse tipo de estrutura é possível operar em cima dela mesma. Todavia, o resultado da operação sempre retorna uma nova estrutura baseada na antiga, compartilhando os elementos para otimizar uso da memória. No Java não temos essas estruturas e é ai que entra o &lt;em&gt;Vavr&lt;/em&gt;. Na biblioteca &lt;em&gt;Vavr&lt;/em&gt; temos a estrutura que representa uma lista ligada conhecida como &lt;em&gt;List&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos visualizar a lista &lt;em&gt;count&lt;/em&gt; como sendo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b4xZDjJZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4ovtdtaqwmretc4e1c7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b4xZDjJZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4ovtdtaqwmretc4e1c7w.png" alt="List(1, 2, 3)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O que acontece se manipularmos a lista substituindo o primeiro elemento por 0 ?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;newCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tail&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;prepend&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A operação acima descarta o primeiro elemento "cabeça" &lt;code&gt;newCount&lt;/code&gt;, retornando a "calda" &lt;code&gt;.tail()&lt;/code&gt;, além de adicionar o elemento 0 como primeiro elemento &lt;code&gt;.prepend(0)&lt;/code&gt;. Por ser uma lista persistente, as operações resultam em uma nova lista chamada &lt;code&gt;newCount&lt;/code&gt;, mantendo a anterior &lt;code&gt;count&lt;/code&gt; intacta com mesmo valor (1, 2 e 3).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PcwF6OQJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/juerwnntfonm287m5373.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PcwF6OQJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/juerwnntfonm287m5373.png" alt="List(0, 2, 3)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O truque aqui é gerar uma nova versão da lista primária, reutilizando os mesmos elementos para otimizar o uso de memória. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Conclusão sobre FP
&lt;/h2&gt;

&lt;p&gt;Não pense que trabalhar com linguagens funcionais é estar 100% conforme as características. Existem momentos onde não da para escapar dos &lt;em&gt;side-effects&lt;/em&gt;. Por exemplo, qualquer funcionalidade que faz I/O (log, stream, req/res, etc.) é um &lt;em&gt;side-effect&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estamos falando tanto em funções, fiquei curioso, você saberia me dizer qual a diferença entre um método e um função?&lt;br&gt;
Bom, um método não existe por si só, ele precisa de uma classe para existir. &lt;br&gt;
A função, por outro lado, pode viver sozinha, flutuando em um arquivo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. Próximos passos
&lt;/h2&gt;

&lt;p&gt;Em breve trarei o segundo post da série: Programação Funcional em Java #2 - Descomplicando Vavr.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vavr.io/vavr-docs/"&gt;Vavr docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.vavr.io/the-agonizing-death-of-an-astronaut/"&gt;The agonizing death of an astronaut&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learnyouahaskell.com/a-fistful-of-monads"&gt;A Fistful of Monads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arrow-kt.io/docs/patterns/monad_comprehensions/"&gt;Monad comprehensions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nofluffjuststuff.com/magazine/2016/11/the_duality_of_pure_functions"&gt;The Duality of Pure Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://alvinalexander.com/scala/functional-programming-simplified-book/"&gt;Functional Programming, Simplified&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>functional</category>
      <category>vavr</category>
      <category>monad</category>
    </item>
  </channel>
</rss>
