<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Mentor and experienced Java programmer]]></title><description><![CDATA[Programming Java Kotlin C C++ Embedded Web 
Clean code Refactoring legacy code
Programming mentor
Consultant ]]></description><link>https://blog.programwithjr.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 02:51:27 GMT</lastBuildDate><atom:link href="https://blog.programwithjr.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Improved Collections in Java 21]]></title><description><![CDATA[Introduction
In Java, there are three fundamental abstractions for grouping data:

List<E>: Index-ordered collection that allows duplicates. Elements maintain their insertion position (ArrayList, Link]]></description><link>https://blog.programwithjr.com/improved-collections-in-java-21</link><guid isPermaLink="true">https://blog.programwithjr.com/improved-collections-in-java-21</guid><category><![CDATA[Java]]></category><category><![CDATA[Java Programming]]></category><category><![CDATA[Modern Java]]></category><category><![CDATA[java collections]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Thu, 02 Apr 2026 18:52:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/38484722-1848-45ee-bb7b-0966803c04fb.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>In Java, there are <strong>three fundamental abstractions</strong> for grouping data:</p>
<ol>
<li><p><code>List&lt;E&gt;</code>: <strong>Index-ordered collection</strong> that <strong>allows duplicates</strong>. Elements maintain their insertion position (<code>ArrayList</code>, <code>LinkedList</code>).</p>
</li>
<li><p><code>Set&lt;E&gt;</code>: Collection of <strong>unique elements</strong>. Can be unordered (<code>HashSet</code>) or ordered by insertion (<code>LinkedHashSet</code>) or natural ordering (<code>TreeSet</code>).</p>
</li>
<li><p><code>Map&lt;K,V&gt;</code>: It is <strong>not a</strong> <code>Collection</code>, but a number of <strong>key-value pairs</strong> with unique keys. Similarly: unordered (<code>HashMap</code>), insertion-ordered (<code>LinkedHashMap</code>), or natural (<code>TreeMap</code>).</p>
</li>
</ol>
<p>These interfaces have been widely used since <strong>JDK 1.2 (1998)</strong>, with <strong>few structural changes</strong> since JDK 5 (2004, generics). However, they had a <strong>critical gap</strong>: there was <strong>no common abstraction</strong> for collections with <strong>defined "encounter order"</strong> (clear first/last element) that unified:</p>
<pre><code class="language-plaintext">List/Deque     vs     LinkedHashSet/SortedSet  (¡no common supertype!)
(duplicates OK)          (unique)
</code></pre>
<p><strong>Java 21 (JEP 431)</strong> introduces <code>SequencedCollection</code>, <code>SequencedSet</code>, and <code>SequencedMap</code>, the <strong>first fundamental interfaces in many years</strong>, resolving this historic inconsistency.</p>
<h2>Ordered Sets</h2>
<h3>The Need for <code>SequencedSet&lt;E&gt;</code></h3>
<p>Before Java 21, developers faced a <strong>structural inconsistency</strong>: collections with <strong>defined encounter order</strong> + <strong>unique elements</strong> existed (<code>LinkedHashSet</code>, <code>NavigableSet</code>), but shared <strong>no common interface</strong>. <code>Set&lt;E&gt;</code> is unordered by definition, forcing API designers to return concrete <code>LinkedHashSet</code> types, violating interface segregation.</p>
<p><strong>Pre-Java 21</strong>:</p>
<pre><code class="language-java">// PROBLEM 1: No abstraction for ordered+unique
public LinkedHashSet&lt;String&gt; getOrderedUniqueItems() {  // Concrete type! Bad API design, an interface should be used
    return new LinkedHashSet&lt;&gt;(items);
}

// PROBLEM 2: Accessing first/last requires hacks
LinkedHashSet&lt;String&gt; set = new LinkedHashSet&lt;&gt;(List.of("C", "A", "B"));
String first = set.iterator().next();        
String last  = null;
Iterator&lt;String&gt; it = set.iterator();
while (it.hasNext()) last = it.next();       // Manual scan!
set.remove(last);                           // Order may shift

// PROBLEM 3: Reverse iteration? Copy to List first
List&lt;String&gt; reversed = new ArrayList&lt;&gt;(set);
Collections.reverse(reversed);              // O(n) copy + reverse
</code></pre>
<p><strong>Java 21 solution</strong> - <code>SequencedSet&lt;E&gt;</code> (extends <code>SequencedCollection&lt;E&gt;</code>):</p>
<pre><code class="language-java">SequencedSet&lt;String&gt; set = new LinkedHashSet&lt;&gt;();
set.addLast("C"); set.addLast("A"); set.addLast("B");  // [C, A, B]

String first = set.getFirst();    // "C" - O(1)
String last  = set.getLast();     // "B"  - O(1)
set.removeFirst();                // [A, B]

// Reordering existing elements (NEW!)
set.addFirst("A");                // Moves A to front: [A, B]
set.addLast("B");                 // Moves B to end:   [A, B]

// Reverse stream - uniform across all sequenced types
set.reversed().stream()
   .forEach(System.out::println);  // B, A
</code></pre>
<h3>Why No <code>SequencedList&lt;E&gt;</code> equivalent?</h3>
<p><code>List&lt;E&gt;</code> and <code>Deque&lt;E&gt;</code> <em>already</em> share the exact operations <code>SequencedCollection</code> provides (<code>getFirst()</code>, <code>removeLast()</code>, etc.). <code>SequencedCollection&lt;E&gt;</code> sits <em>between</em> <code>Collection&lt;E&gt;</code> and both:</p>
<pre><code class="language-mermaid">graph TB
    Collection --&gt; SC[SequencedCollection]
    SC --&gt; List["List&lt;E&gt;"]
    SC --&gt; Deque["Deque&lt;E&gt;"]
    
    classDef sequenced fill:#bbdefb,stroke:#01579b,stroke-width:2px
    classDef standard fill:#f5f5f5
    class SC sequenced
    class List,Deque standard
</code></pre>
<p><code>List</code> gained <code>SequencedCollection</code> methods <em>for free</em>. No need for a <code>SequencedList</code> wrapper—<code>List&lt;E&gt;</code> <em>is</em> already sequenced.</p>
<h3>Why Tail Elements Matter</h3>
<p>Accessing <strong>first/last elements</strong> (tail elements) is a <strong>fundamental operation</strong> in ordered collections, yet in <strong>pre-Java 21</strong> it could be <strong>error-prone</strong>. Developers constantly needed <strong>temporary variables</strong> just to compute indices, leading to off-by-one errors.</p>
<p><strong>Pre-Java 21</strong>:</p>
<pre><code class="language-java">List&lt;String&gt; items = fetchItemsFromDatabase();  // Simulate expensive fetch
int lastIndex = items.size() - 1;              // Temp var #1: index calculation
String lastItem = items.get(lastIndex);        // Temp var #2: store result
processLastItem(lastItem);                     // Finally use it

// Or inline 
String firstItem = items.isEmpty() ? null : items.get(0);  // Null check + index
</code></pre>
<p>// Example - Processing latest log entry:</p>
<pre><code class="language-java">List&lt;LogEntry&gt; logs = readLogFile();  // 10k+ entries
if (!logs.isEmpty()) {
    int lastIdx = logs.size() - 1;               // Temporary variable for index
    LogEntry latest = logs.get(lastIdx);         // Another temporary variable
    sendAlert(latest.getLevel(), latest.getTime()); 
}
</code></pre>
<p><strong>Post-JDK 21</strong>:</p>
<pre><code class="language-java">List&lt;LogEntry&gt; logs = readLogFile();
if (!logs.isEmpty()) {
    LogEntry latest = logs.getLast();         // Direct! No temporary variables
    sendAlert(latest.getLevel(), latest.getTime());
}

// Even inlines perfectly:
processLastItem(fetchItemsFromDatabase().getLast());  // Zero boilerplate
</code></pre>
<p><strong>Why this matters technically</strong>:</p>
<ul>
<li><p><strong>Eliminates</strong> <code>size()-1</code> <strong>bug</strong> (most common List off-by-one error)</p>
</li>
<li><p><strong>Uniform API</strong> across <code>List</code>, <code>Deque</code>, <code>LinkedHashSet</code> via <code>SequencedCollection</code></p>
</li>
</ul>
<h2>Ordered Maps</h2>
<h3>The Need for <code>SequencedMap&lt;K,V&gt;</code></h3>
<p>As it has been explained with Set, <strong>Pre-Java 21</strong>, <code>Map&lt;K,V&gt;</code> implementations with <strong>defined encounter order</strong> (<code>LinkedHashMap</code>, <code>NavigableMap</code>) lacked a <strong>common interface</strong>, forcing concrete types in APIs and <strong>inconsistent endpoint operations</strong>. <code>Map</code> naming conventions were also fragmented (<code>firstEntry()</code> vs <code>pollFirstEntry()</code> vs no operations at all).</p>
<p><strong>Pre-Java 21</strong>:</p>
<pre><code class="language-java">// PROBLEM 1: Concrete types in APIs
public LinkedHashMap&lt;String, Integer&gt; getOrderedScores() {  // Bad API design, an interface should be used
    return new LinkedHashMap&lt;&gt;();
}

// PROBLEM 2: No consistent first/last access
LinkedHashMap&lt;String, Integer&gt; map = new LinkedHashMap&lt;&gt;();
map.put("C", 3); 
map.put("A", 1); 
map.put("B", 2);  // Order: C,A,B

// First entry? Iterator hack
Map.Entry&lt;String, Integer&gt; first = map.entrySet().iterator().next();  // O(n)

// Last entry? Manual scan
Map.Entry&lt;String, Integer&gt; last = null;
for (Map.Entry&lt;String, Integer&gt; e : map.entrySet()) {
    last = e;
}
</code></pre>
<p><strong>Java 21 solution</strong> - <code>SequencedMap&lt;K,V&gt;</code>:</p>
<pre><code class="language-java">SequencedMap&lt;String, Integer&gt; map = new LinkedHashMap&lt;&gt;();
map.putLast("C", 3); 
map.putLast("A", 1); 
map.putLast("B", 2);  // [C,A,B]

Map.Entry&lt;String, Integer&gt; first = map.firstEntry();   // O(1) - "C"=3
Map.Entry&lt;String, Integer&gt; last  = map.lastEntry();    // O(1) - "B"=2

// Remove + return (poll semantics from NavigableMap)
Map.Entry&lt;String, Integer&gt; removed = map.pollLastEntry();  // "B"=2, map=[C,A]

// Reordering existing keys (NEW!)
map.putFirst("A", 99);  // Updates A, moves to front: [A, C]
</code></pre>
<h2>Sequenced Map Views</h2>
<p><strong>Unique to maps</strong>: Three <strong>sequenced projections</strong> that preserve order:</p>
<pre><code class="language-java">SequencedMap&lt;String, Integer&gt; scores = new LinkedHashMap&lt;&gt;();
scores.put("Z", 26); 
scores.put("A", 1); 
scores.put("M", 13);

// Traditional views (unordered!)
Set&lt;String&gt; keys = scores.keySet();           // HashSet - order lost!

// NEW: Sequenced views preserve encounter order
SequencedSet&lt;String&gt; seqKeys = scores.sequencedKeySet();    // [Z, A, M]
seqKeys.removeFirst();  // Removes "Z" from original map!
</code></pre>
<p><strong>Real-world example</strong> - <strong>LRU Cache simulation</strong>:</p>
<pre><code class="language-java">SequencedMap&lt;String, Integer&gt; cache = new LinkedHashMap&lt;&gt;();
cache.putLast("key1", 100);
cache.putLast("key2", 200);

// "Touch" key1 (move to end)
cache.putLast("key1", 150);  // Now: [key2, key1]

// Evict oldest
cache.pollFirstEntry();      // Removes key2
</code></pre>
<h3>Map Hierarchy</h3>
<pre><code class="language-mermaid">graph TB
    Map --&gt; SM["SequencedMap&lt;K,V&gt;"]
    SM --&gt; SortedMap
    SortedMap --&gt; NavigableMap
    LHM["LinkedHashMap"]
    SM -.-&gt; LHM
    
    classDef new fill:#bbdefb,stroke:#01579b
    classDef impl fill:#f3e5f5
    class SM new
    class LHM impl
</code></pre>
<h3>Key Technical Differences</h3>
<table>
<thead>
<tr>
<th>Operation</th>
<th><code>SequencedCollection</code></th>
<th><code>SequencedMap</code></th>
</tr>
</thead>
<tbody><tr>
<td><strong>Add</strong></td>
<td><code>addFirst(E)</code></td>
<td><code>putFirst(K,V)</code></td>
</tr>
<tr>
<td><strong>Get</strong></td>
<td><code>getFirst()</code> <strong>(throws)</strong></td>
<td><code>firstEntry()</code> <strong>(null-safe)</strong></td>
</tr>
<tr>
<td><strong>Remove</strong></td>
<td><code>removeFirst()</code> <strong>(throws)</strong></td>
<td><code>pollFirstEntry()</code> <strong>(null-safe)</strong></td>
</tr>
<tr>
<td><strong>Views</strong></td>
<td>N/A</td>
<td><code>sequencedKeySet()</code>, <code>sequencedEntrySet()</code></td>
</tr>
</tbody></table>
<h2>Reverse Streams</h2>
<p><strong>Pre-Java 21 hacks</strong>:</p>
<pre><code class="language-java">Stream&lt;String&gt; reversed = IntStream.range(0, list.size())
    .mapToObj(i -&gt; list.get(list.size()-1-i));
</code></pre>
<p><strong>Java 21 solution</strong> - Works everywhere:</p>
<pre><code class="language-java">// List, Set, Map views - uniform!
list.reversed().stream()
linkedHashSet.reversed().stream()
map.sequencedKeySet().reversed().stream()
    .filter(s -&gt; s.startsWith("A"))
    .forEach(System.out::println);
</code></pre>
<p><strong>Example</strong>: Log processing:</p>
<pre><code class="language-java">logEntries.reversed().stream()    // Newest first
    .filter(LogEntry::isError)
    .limit(5)
    .forEach(LogAnalyzer::process);
</code></pre>
<h2>Why "Sequenced" Instead of "Ordered"?</h2>
<p><strong>Not "OrderedSet"</strong> because:</p>
<ol>
<li><p><code>SortedSet</code> already exists (natural/comparator order, like <code>TreeSet</code>)</p>
</li>
<li><p><strong>"Encounter order"</strong> ≠ <strong>sorted order</strong>:</p>
<pre><code class="language-java">NavigableSet&lt;Integer&gt; sorted = new TreeSet&lt;&gt;(List.of(3, 1, 2));  // [1,2,3]
LinkedHashSet&lt;Integer&gt; seqd  = new LinkedHashSet&lt;&gt;(List.of(3,1,2)); // [3,1,2]
</code></pre>
</li>
<li><p><code>SequencedSet</code> preserves <strong>insertion order</strong> (or stable order), not sorted order</p>
</li>
<li><p><strong>Terminology consistency</strong>: Matches Stream API's "encounter order" concept [JEP 431]</p>
</li>
</ol>
<p><strong>Key distinction</strong>:</p>
<pre><code class="language-java">SequencedSet&lt;Integer&gt; seq = new LinkedHashSet&lt;&gt;(List.of(3, 1, 2));  // [3,1,2]
SortedSet&lt;Integer&gt; sorted = new TreeSet&lt;&gt;(seq);                    // [1,2,3]
</code></pre>
<h3>Collection Hierarchy</h3>
<p><a href="https://postimg.cc/5XTS5V0j" target="_blank"><img src="https://i.postimg.cc/5XTS5V0j/mermaid-diagram-2026-04-02-210402.png" alt="mermaid-diagram-2026-04-02-210402" /></a></p>
]]></content:encoded></item><item><title><![CDATA[Java Data Types at a glance]]></title><description><![CDATA[Java Data Types
Java requires specifying the data type when declaring a variable.This has two goals:

To know how many memory locations are used.

To know which operations can be performed on the data]]></description><link>https://blog.programwithjr.com/java-data-types-at-a-glance</link><guid isPermaLink="true">https://blog.programwithjr.com/java-data-types-at-a-glance</guid><category><![CDATA[Java]]></category><category><![CDATA[#boxing]]></category><category><![CDATA[data types]]></category><category><![CDATA[Kotlin]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Sat, 03 Jan 2026 18:56:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/f541212e-5f51-4bbb-9458-5b1e787bd109.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Java Data Types</h1>
<p>Java requires specifying the data type when declaring a variable.<br />This has two goals:</p>
<ul>
<li><p>To know how many memory locations are used.</p>
</li>
<li><p>To know which operations can be performed on the data. The basic operations are addition, subtraction, multiplication, division and remainder or modulo: <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>%</code>.</p>
</li>
</ul>
<p>A <strong>primitive type</strong> is a data type that is defined directly in the Java programming language.</p>
<h2>Primitive types</h2>
<p>As in almost all programming languages, Java has the following primitive data types:</p>
<ul>
<li><p>For integer numbers: <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code>.</p>
</li>
<li><p>For floating‑point numbers: <code>float</code> and <code>double</code>.</p>
</li>
<li><p>For characters: <code>char</code>.</p>
</li>
<li><p>For logical values (only two possible values): <code>boolean</code>.</p>
</li>
</ul>
<p>In total, Java has eight primitive types: <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code>, <code>char</code>, <code>float</code>, <code>double</code> and <code>boolean</code>.</p>
<p><code>String</code> is the only basic predefined data type that is widely used but <strong>is not</strong> a primitive type; it is a class.</p>
<h2>Wrapper types</h2>
<p>A <strong>wrapper type</strong> is a predefined class that encapsulates a value of a primitive type:</p>
<ul>
<li><p><code>Integer</code> wraps the primitive type <code>int</code>.</p>
</li>
<li><p><code>Long</code> wraps the primitive type <code>long</code>.</p>
</li>
<li><p><code>Character</code> wraps the primitive type <code>char</code>.</p>
</li>
<li><p><code>Float</code> wraps the primitive type <code>float</code>.</p>
</li>
<li><p><code>Double</code> wraps the primitive type <code>double</code>.</p>
</li>
<li><p><code>Boolean</code> wraps the primitive type <code>boolean</code>.</p>
</li>
<li><p><code>Byte</code> wraps the primitive type <code>byte</code>.</p>
</li>
<li><p><code>Short</code> wraps the primitive type <code>short</code>.</p>
</li>
</ul>
<h2>Difference between primitive types and other data types</h2>
<p>Primitive types are not objects and therefore do not have an associated class directly.</p>
<pre><code class="language-java">int monthNumber = 5;
System.out.println(monthNumber);
</code></pre>
<p>In data structures that require objects, such as map keys, you must use wrapper types. For example, the key can be of type <code>Integer</code>, but not of type <code>int</code>.</p>
<p>The following is incorrect:</p>
<pre><code class="language-java">Map&lt;int, String&gt; months = new HashMap&lt;&gt;();   // Incorrrect, because a map's key must be an object
</code></pre>
<p>This, however, is correct:</p>
<pre><code class="language-java">int monthNumber = 5;
Map&lt;Integer, String&gt; months = new HashMap&lt;&gt;();
months.put(monthNumber, "May");
</code></pre>
<p>In this and similar cases, the compiler automatically converts the primitive type <code>int</code> into the wrapper type <code>Integer</code>. This technique is called <em>autoboxing</em> (and the reverse conversion is called <em>unboxing</em>).</p>
<p>All Java objects inherit from the <code>Object</code> class. Since primitive types are not objects, they cannot use methods from <code>Object</code>, such as <code>equals()</code>, <code>wait()</code> or <code>notify()</code>.</p>
<h2>Objects and references</h2>
<p>Objects are normally created with the <code>new</code> keyword (or via constructors and factories). Primitive types are declared simply using their type and the variable name.</p>
<pre><code class="language-java">int monthNumber = 5;
Integer otherMonthNumber = new Integer(5); // nowadays Integer.valueOf(5) is preferred
</code></pre>
<p>In other words, a reference‑type variable stores a <strong>reference</strong> to a memory area where the object is located. A primitive‑type variable stores the value directly in the memory associated with that variable.<br />A reference is conceptually similar to a pointer in the C language, although in Java it cannot be manipulated explicitly.</p>
<h2>Data types and memory</h2>
<ul>
<li><p>The data type that uses the least memory is <code>byte</code>, which occupies only one byte. Its value range goes from -128 to 127.</p>
</li>
<li><p><code>short</code> occupies two bytes and its range goes from -32,768 to 32,767 (<code>Short.MIN_VALUE</code> to <code>Short.MAX_VALUE</code>).</p>
</li>
<li><p><code>int</code> occupies four bytes and its range goes from -2,147,483,648 to 2,147,483,647 (<code>Int.MIN_VALUE</code> to <code>Int.MAX_VALUE</code>).</p>
</li>
<li><p><code>long</code> occupies eight bytes and its range goes from <code>Long.MIN_VALUE</code> to <code>Long.MAX_VALUE</code>.</p>
</li>
</ul>
<p>Notice the symmetry in signed integer types: the total number of negative values is equal to the total number of positive values, considering that zero is counted on the positive side.<br />Unlike languages such as C or C++, Java does not have <code>unsigned</code> integer types.</p>
<ul>
<li><p><code>char</code> occupies two bytes and represents values from 0 to 65,535 (Unicode characters).</p>
</li>
<li><p><code>float</code> occupies four bytes.</p>
</li>
<li><p><code>double</code> occupies eight bytes.</p>
</li>
<li><p>The specification does not fix the physical size of <code>boolean</code>; logically it represents only two possible values (<code>true</code> and <code>false</code>).</p>
</li>
</ul>
<h2>Syntax for <code>long</code>, <code>float</code> and <code>double</code> literals</h2>
<ul>
<li><p>A <code>long</code> literal may have the suffix <code>L</code> or <code>l</code> (it is recommended to use <code>L</code> to avoid confusion with the digit 1).</p>
</li>
<li><p>A <code>float</code> literal must have the suffix <code>F</code> or <code>f</code>.</p>
</li>
<li><p>A <code>double</code> literal may have the suffix <code>D</code> or <code>d</code>, although it is usually omitted because <code>double</code> is the default type for floating‑point literals.</p>
</li>
</ul>
<pre><code class="language-java">long   x = 1L;
float  f = 1.0f;
double y = 1.0;
</code></pre>
<h2>Digit separator</h2>
<ul>
<li><p>The separator between integer and fractional part is the dot, and it is mandatory in decimal numbers.</p>
</li>
<li><p>The thousands separator may be an underscore <code>_</code>. It is optional, but improves readability of large numbers. It was introduced in Java 7.</p>
</li>
</ul>
<pre><code class="language-java">long   x = 1_000_000L;
double y = 1_000_000.0;
</code></pre>
<h2>Scientific notation</h2>
<ul>
<li><p>The exponent is written using the letter <code>e</code> or <code>E</code>.</p>
</li>
<li><p>In scientific notation, the literal becomes a <code>double</code> by default, unless it is explicitly marked as <code>float</code>.</p>
</li>
</ul>
<pre><code class="language-java">double y = 1e6;   // 1.0 × 10^6
double z = 1e6D;  // equivalent to the line above
float  f = 1e6f;  // float
</code></pre>
<p>(Using <code>e</code> with a <code>long</code> literal is not correct; <code>1e6</code> is a floating‑point literal, not a <code>long</code>.)</p>
<h2>Precision of decimal numbers</h2>
<ul>
<li><p>To use <code>float</code>, the literal must end with <code>f</code> or <code>F</code>.</p>
</li>
<li><p>To use <code>double</code>, you may use <code>d</code> or <code>D</code>, but in practice it is usually omitted, since <code>double</code> is the default type.</p>
</li>
</ul>
<pre><code class="language-java">float  f = 3.1415927f;
double d = 3.141592653589793;
</code></pre>
<p>The <code>float</code> and <code>double</code> types represent floating‑point numbers in binary, and therefore they cannot represent exactly most decimal fractions that are simple in base 10.</p>
<h2>Type promotion</h2>
<p>Java performs numeric promotion automatically when primitive numeric types are used in expressions with operators like +, -, *, /, %, or in comparisons.</p>
<p>Core Rules</p>
<ul>
<li><p>byte, short, char → always promoted to int first</p>
</li>
<li><p>If any operand is long → both promoted to long</p>
</li>
<li><p>If any operand is float → both promoted to float</p>
</li>
<li><p>If any operand is double → both promoted to double</p>
</li>
</ul>
<pre><code class="language-java">byte b = 100;
short s = 200;
// b + s promotes to int (compile error if assigned to byte/short)
int result = b + s;  

long big = 1_000_000L;
int small = 42;
long total = big + small;  // int -&gt; long
</code></pre>
<h2><code>BigInteger</code> and <code>BigDecimal</code> classes</h2>
<p>The <code>BigInteger</code> and <code>BigDecimal</code> classes are used to represent very large numbers or to perform calculations with high numeric precision.</p>
<p>In the case of <code>BigDecimal</code>, numbers are represented in decimal form (not as binary floating point), which allows arithmetic operations without the typical rounding errors of <code>float</code> and <code>double</code> when working, for example, with money.</p>
<pre><code class="language-java">// float/double PROBLEM (binary floating point)
double money = 0.1 + 0.2;  // 0.30000000000000004 ❌

// BigDecimal SOLUTION (decimal arithmetic)  
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
BigDecimal money = bd1.add(bd2);  // 0.3 exactly ✅
</code></pre>
<p>BigDecimal stores decimal digits + scale, not fractions p/q or rational numbers: 1/3 becomes "0.333333" (truncated/rounded), not the exact rational 1/3.</p>
<ul>
<li>Therefore, division operations always require <strong>scale</strong> and <strong>rounding</strong> modes.</li>
</ul>
<h2>Identity and equality</h2>
<p>For primitive types, the value is the data itself; two primitive variables are “equal” if they contain the same value.<br />For reference types (objects), <strong>identity</strong> is determined by the reference (the logical address of the object), and <strong>logical equality</strong> is usually defined by the <code>equals()</code> method.</p>
<h2>Autoboxing</h2>
<p>As the official documentation says:</p>
<blockquote>
<p>The result of all this magic is that you can largely ignore the distinction between int and Integer, with a few caveats. An Integer expression can have a null value. If your program tries to autounbox null, it will throw a NullPointerException. The == operator performs reference identity comparisons on Integer expressions and value equality comparisons on int expressions. Finally, there are performance costs associated with boxing and unboxing, even if it is done automatically.</p>
</blockquote>
<h2>When to use primitive types</h2>
<ul>
<li><p>The use of primitive types in modern Java is not just about maintaining backward compatibility (autoboxing and unboxing techqniques were introduced in Java 5).</p>
</li>
<li><p>In some cases, it's preferable to use primitive types for performance reasons, for example in big loops or in web applications with a very large volume of users.</p>
</li>
</ul>
<h1>Kotlin Data Types</h1>
<p>Kotlin only works with <strong>objects</strong>, not with primitives in the Java sense.</p>
<ul>
<li><p>Types like <code>Int</code>, <code>Long</code>, <code>Double</code>, <code>Boolean</code>, <code>Char</code>, etc. are regular classes from the Kotlin point of view, and you can call methods and properties on them (<code>10.toString()</code>).</p>
</li>
<li><p>There is no separate <code>int</code>/<code>Integer</code> distinction in the syntax like in Java; you always write <code>Int</code>, <code>Long</code>, <code>Double</code>, and so on.</p>
</li>
</ul>
<h2>What happens at runtime</h2>
<ul>
<li><p>On the JVM, the compiler <strong>optimizes</strong> these types to real JVM primitives (<code>int</code>, <code>long</code>, <code>double</code>, etc.) whenever possible, so performance is equivalent to using primitives in Java.</p>
</li>
<li><p>When a primitive‑like value must behave as an object (for example, when used in a generic type or stored in a <code>List&lt;Int&gt;</code>), the compiler uses the corresponding wrapper (<code>java.lang.Integer</code>, <code>java.lang.Long</code>, etc.), boxing and unboxing automatically. Primitive representations exist only as an implementation detail for efficiency on the JVM platform.</p>
</li>
</ul>
<h2>Unsigned types</h2>
<p>Kotlin supports unsigned integer types (UInt, ULong, etc.) for positive-only values without sign bit. Java lacks these, as we have explained above.</p>
]]></content:encoded></item><item><title><![CDATA[How to create a class - Best Practices]]></title><description><![CDATA[Introduction
We will explain how to create an object in Java. It has evolved from the old Javabeans to the use of features in the latest versions of the language.
Setters and getters
We have a Person ]]></description><link>https://blog.programwithjr.com/how-to-create-a-class-best-practices</link><guid isPermaLink="true">https://blog.programwithjr.com/how-to-create-a-class-best-practices</guid><category><![CDATA[Java]]></category><category><![CDATA[immutability]]></category><category><![CDATA[java 17]]></category><category><![CDATA[Records]]></category><category><![CDATA[javabeans]]></category><category><![CDATA[factory]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Tue, 22 Jul 2025 11:52:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/cc54543e-fe4a-4625-b348-cd4ebbf4006d.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>We will explain how to create an object in Java. It has evolved from the old Javabeans to the use of features in the latest versions of the language.</p>
<h2>Setters and getters</h2>
<p>We have a Person with three attributes: name, age and gender.</p>
<pre><code class="language-java">import java.util.Objects;

public class Person {

    private String name;
    private int age;
    private String gender;

    public Person(String name, int age, String gender) {
        this.name = name; 
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Gender getGender() {
       return gender;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + '}';
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.getAge() &amp;&amp; name.equals(person.getName()) &amp;&amp; gender.equals(person.getGender());
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, gender);
    }
}
</code></pre>
<p>Any IDE can generate all the above methods. But...... we can do it better.</p>
<h2>Validation</h2>
<p>Imagine the client wants to create a Person with a negative age or a with no name. Our API must take care of that in the constructor:</p>
<pre><code class="language-java">public Person(String name, int age, String gender) {
    if (name == null || name.isBlank()) {
        throw new IllegalArgumentException("Invalid name");
    }
    if (age &lt; 0) {
        throw new IllegalArgumentException("Age cannot be negative");
    }
    if (gender == null || gender.isBlank()) {
        throw new IllegalArgumentException("Invalid gender");
    }
    this.name = name;
    this.age = age;
    this.gender = gender;
}
</code></pre>
<h2>Static factory methods</h2>
<p>Instead of having the client call the traditional constructor, our API can provide a number of descriptive methods, so that the client can choose the most appropriate one. This pattern is very common in the JDK. For example, the <code>Instance</code> class (from the Java Time API) includes static factory methods such as <code>now()</code>, <code>of()</code>, <code>from()</code>, and <code>parse()</code>.</p>
<pre><code class="language-java">    public static Person of(String name, int age, Gender gender) {
        return new Person(name, age, gender);
    }

    public static Person createATwentyYearOldMale(String name) {
        return new Person(name, 20, Gender.MALE);
    }

    public static Person createATwentyYearOldFemale(String name) {
        return new Person(name, 20, Gender.FEMALE);
    }
</code></pre>
<pre><code class="language-java">public enum Gender {
    MALE,
    FEMALE
}
</code></pre>
<p>Thanks to the enumeration class, we change the gender parameter from String type to Gender type. This allows to <strong>catch errors in compilation time</strong>.</p>
<pre><code class="language-java">    Person person = Person.of("John", 25, Gender.MALE);
    var person2 = Person.createATwentyYearOldMale("John");
    var person3 = Person.of("John", 25, "men");     // Compilation error
</code></pre>
<p>It is important to note that <strong>the constructor is now private</strong>, so that the client cannot create directly objects of this class:</p>
<pre><code class="language-java">    var person = new Person("Alice", 25, Gender.FEMALE);     // Compilation error
</code></pre>
<p>Other benefit of having the constructor private is that the client cannot extend the Person class:</p>
<pre><code class="language-java">    class Woman extends Person {  // Compilation error
        ...................
    }
</code></pre>
<p>This is a good thing, because we want to be able to control what the client can do with our API.</p>
<h2>Non extensible class</h2>
<p>However, to make the intent clear in the Javadoc documentation, we can use the <strong>final</strong> modifier:</p>
<pre><code class="language-java">    public final class Person {
        ...................
    }
</code></pre>
<p>We will talk about restricted inheritance later.</p>
<h2>No setters</h2>
<p>Although the setter methods were heavily used in the Javabeans days, programmers came to realize that <strong>immutable objects</strong> made in in many cases the code easier to read, especially in concurrent applications. In other words, creating an object every time an attribute changes its value. This is quite similar to how purely functional languages work.</p>
<pre><code class="language-java">    public Person withName(String newName) {
        return new Person(newName, this.age, this.gender);
    }

    public Person withAge(int newAge) {
        return new Person(this.name, newAge, this.gender);
    }

    public Person withGender(Gender newGender) {
        return new Person(this.name, this.age, newGender);
    }
</code></pre>
<p>and make the attributes immutable, too:</p>
<pre><code class="language-java">    private final String name;
    private final int age;
    private final Gender gender;
</code></pre>
<p>The <code>with</code> prefix is a common convention and these methods are called <code>withers</code>.</p>
<h2>Records</h2>
<p>A record is a class that is <strong>immutable</strong>(its attributes cannot be changed) and <strong>final</strong>. It was introduced as a preview feature in Java 14 and the first LTS version that included it was Java 17.</p>
<pre><code class="language-java">public record Person(String name, int age, Gender gender) {}
</code></pre>
<p>The record class automatically generates private final attributes, and implements the <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> methods.</p>
<p>We only have to write this code:</p>
<pre><code class="language-java">public record Person(String name, int age, Gender gender) {
    
    // Validation rules
    public Person {   // The compact constructor doesn't have any parameters
        if (name == null || name.isBlank())
            throw new IllegalArgumentException("Name cannot be null or blank");
        if (age &lt; 0)
            throw new IllegalArgumentException("Age cannot be negative");
        if (gender == null || gender.isBlank()) 
            throw new IllegalArgumentException("Invalid gender");
    }

    // Static factory methods
    public static Person of(String name, int age, Gender gender) {
        return new Person(name, age, gender);
    }

    public static Person createATwentyYearOldMale(String name) {
        return new Person(name, 20, Gender.MALE);
    }

    public static Person createATwentyYearOldFemale(String name) {
        return new Person(name, 20, Gender.FEMALE);
    }

    // Wither-methods
    public Person withName(String newName) {
        return new Person(newName, this.age, this.gender);
    }

    public Person withAge(int newAge) {
        return new Person(this.name, newAge, this.gender);
    }

    public Person withGender(Gender newGender) {
        return new Person(this.name, this.age, newGender);
    }
}
</code></pre>
<p>The public accessor methods generated for each component have the same name as the corresponding attribute, they are not getters anymore:</p>
<pre><code class="language-java">    var personJohn = Person.of("John", 25, Gender.MALE);
    System.out.println("Name: " + personJohn.name());     // Accesor method if Person is a record
    System.out.println("Name: " + personJohn.getName());  // Compiler error if Person is a record
</code></pre>
<p>There are two caveats with records:</p>
<ul>
<li><p>The public constructor of a record, called <strong>canonical constructor</strong>, is part of the interface. It can't be made private. As a consequence, the client is not forced to call the static factories.</p>
</li>
<li><p>The <code>wither</code> methods are not yet generated by the compiler.<br />  The JEP ("Java Enhancement Proposal") 468 introduces <strong>derived record creation</strong>, which consists of generating “wither” methods automatically. But this technique, as of July 2025, is not even in preview yet.</p>
</li>
</ul>
<h3>When not to use records</h3>
<p>If we have a class with a complex business logic (many static factories, for example), regular classes are better suited than records, as they are more flexible.</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Regular Class</th>
<th>Record</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Purpose</strong></td>
<td>General-purpose, can encapsulate state and behavior</td>
<td>Immutable data carrier, concise data-only types</td>
</tr>
<tr>
<td><strong>Mutability</strong></td>
<td>Can be mutable or immutable</td>
<td>Immutable by default (all fields are final)</td>
</tr>
<tr>
<td><strong>Inheritance</strong></td>
<td>Can extend another class (single inheritance) and implement interfaces</td>
<td>Cannot extend any class; can only implement interfaces</td>
</tr>
<tr>
<td><strong>Constructors</strong></td>
<td>Any number, including no-arg and overloaded</td>
<td>Canonical constructor auto-generated; can add custom constructors (with restrictions)</td>
</tr>
<tr>
<td><strong>Boilerplate code</strong></td>
<td>Require manual implementation of getters, setters, <code>equals</code>, <code>hashCode</code>, etc.</td>
<td>Getters, canonical constructor, <code>equals</code>, <code>hashCode</code>, and <code>toString</code> auto-generated</td>
</tr>
<tr>
<td><strong>State-changing methods</strong></td>
<td>Can have methods that mutate fields</td>
<td>Cannot have mutator methods for fields (fields are final)</td>
</tr>
<tr>
<td><strong>Field Declaration</strong></td>
<td>Fields can have any visibility and can be static or final</td>
<td>All fields are implicitly <code>private</code> and <code>final</code>, based on record components</td>
</tr>
<tr>
<td><strong>Use Case</strong></td>
<td>Complex logic, behaviors, mutable patterns, frameworks requiring mutability</td>
<td>Data transfer, value objects, DTOs, where immutability is desired</td>
</tr>
<tr>
<td><strong>Compatibility with JPA</strong></td>
<td>Fully compatible, allows setters, no-arg constructor</td>
<td>Not suitable for JPA entities (no setters, no-arg constructor not provided)</td>
</tr>
</tbody></table>
<h2>Summary</h2>
<p>We have explained the best practices for declaring objects in Java.</p>
<p>Since the (not so good) old Java Beans, the principles of immutability and inheritance prohibition have been applied.</p>
<p>The implementation of records in Java 17 have greatly simplified the creation of objects without having to use libraries similar to <strong>Lombok</strong>.</p>
<p>However, in some cases it is still more convenient to use a regular class.</p>
]]></content:encoded></item><item><title><![CDATA[Hash Tables and hashCode()]]></title><description><![CDATA[Introduction
When creating a class in Java, there are three methods that are commonly overridden:

equals()

hashCode()

toString()


This article focuses on the hashCode() method.
How a hash table wo]]></description><link>https://blog.programwithjr.com/hash-tables-and-hashcode</link><guid isPermaLink="true">https://blog.programwithjr.com/hash-tables-and-hashcode</guid><category><![CDATA[Java]]></category><category><![CDATA[Core Java]]></category><category><![CDATA[Hash]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Wed, 18 Jun 2025 19:33:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/f57c597b-8349-4bc1-8fbc-b6c27601a490.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>When creating a class in Java, there are three methods that are commonly overridden:</p>
<ul>
<li><p><code>equals()</code></p>
</li>
<li><p><code>hashCode()</code></p>
</li>
<li><p><code>toString()</code></p>
</li>
</ul>
<p>This article focuses on the <code>hashCode()</code> method.</p>
<h2>How a hash table works</h2>
<p>Java uses the value returned by the <code>hashCode()</code> method to determine the position of an object in a hash table. But what is a hash table ?</p>
<p><strong>Hash tables</strong> are data structures designed to store and retrieve elements efficiently, avoiding the sequential order of traditional arrays.</p>
<p>Imagine a table with 19 slots. The position (or index) of each value in the hash table is determined by a function such as:</p>
<pre><code class="language-java">@Override
public int hashCode() {
    return value % tableSize;
}
</code></pre>
<p>A common and simple way to define the <code>hashCode()</code> method is to return the remainder of the division between the value to be stored and the table size.</p>
<p>For example, to store the value 20:</p>
<pre><code class="language-java">@Override
public int hashCode() {
    return 20 % 19;  // remainder of 20 / 19
}
</code></pre>
<p>To store the value 21:</p>
<pre><code class="language-java">@Override
public int hashCode() {
    return 21 % 19;
}
</code></pre>
<p>So, the value 20 is stored at index 1, also called first bucket; the value 21 at index 2, and so on.</p>
<p>This approach ensures that the hash code is always within the bounds of the table, distributing the objects across the available slots.</p>
<p>For example, if the table size is 19 and we need to store the first sixty natural numbers, the hash table might look like this:</p>
<pre><code class="language-mermaid">graph TD
    subgraph Hash Table
        slot0["Slot 0"]
        slot1["Slot 1"]
        slot2["Slot 2"]
        slot3["Slot 3"]
        slot4["Slot 4"]
    end

    slot0 --&gt; A1["19"]
    A1 --&gt; A2["39"]
    A2 --&gt; A3["59"]

    slot1 --&gt; B1["20"]
    B1 --&gt; B2["40"]
    B2 --&gt; B3["60"]

    slot2 --&gt; C1["21"]
    C1 --&gt; C2["41"]

    slot3 --&gt; D1["22"]
    D1 --&gt; D2["42"]

    slot4 --&gt; E1["23"]
    E1 --&gt; E2["43"]
</code></pre>
<p>The first two slots has an associated linked list of three elements and the rest of the slots have linked lists of two elements.</p>
<h2>Using prime numbers for the hash functions</h2>
<p>We chose 19 as the table size because it is a prime number. The possible remainders (hash values) are all the integers from 0 up to 18, inclusive. This means every input value will be mapped to one of 19 possible slots. Choosing a prime number as the table size ensures that the hash values are distributed uniformly across the slots, minimizing collisions.</p>
<h2>Collisions</h2>
<p>A collision occurs when more than one value is mapped to the same slot or bucket.</p>
<p>The solution, as shown in the previous example, is using a linked list for each slot (a technique called <strong>separate chaining</strong>). This way, multiple values can coexist in the same bucket, and the hash table can still function correctly. However, the performance can degrade if too many collisions occur.</p>
<h2>Other considerations for hash functions</h2>
<p>Prime numbers are often used when the hash function is simple, but there are reasons why they are not always chosen:</p>
<ul>
<li><p>Computational performance Many modern implementations prefer table sizes that are powers of 2 (e.g., 32, 64, 128) because they allow calculating the hash index using bitwise operations, which are faster than using the modulo operation. If the hash function distributes values well, primes may not be necessary.</p>
</li>
<li><p>Dynamic resizing Some resizing strategies (like doubling the table size) produce sizes that are powers of 2, not primes. This strategy simplifies memory management and reduces computational overhead.</p>
</li>
</ul>
<h2>Commonly used hash functions</h2>
<p>The pattern of multiplying by 31 and combining field values is widely used and recommended in the Java community.</p>
<ul>
<li><p>The use of 31 as a multiplier is standard because it is an odd prime, which helps produce a good distribution of hash codes.</p>
</li>
<li><p>This approach combines the values of all the class fields in a way that reduces the likelihood of collisions.</p>
</li>
<li><p>The general pattern is:</p>
</li>
</ul>
<pre><code class="language-java">public int hashCode() {
    int result = 1;
    result = 31 * result + field1;
    result = 31 * result + field2;
    // ... and so on for more fields
    return result;
}
</code></pre>
<p>Since Java 8, the <code>Objects.hashCode()</code> method can also be used to generate hash codes:</p>
<pre><code class="language-java">@Override
public int hashCode() {
    return Objects.hash(firstField, secondField, ..., nField);
}
</code></pre>
<ul>
<li><p>This method is more concise and automatically combines the hash codes of the provided fields.</p>
</li>
<li><p>Internally, it creates an array of the arguments and then calls <code>Arrays.hashCode()</code> on that array.</p>
</li>
<li><p>It handles null values gracefully, returning 0 for any null field.</p>
</li>
</ul>
<h3>Which one to use</h3>
<p><code>Objects.hash()</code> improves readability and reduces boilerplate, especially for classes with many fields.</p>
<p>Manual hash code gives you more control and may be preferred in performance-sensitive or very large-scale scenarios. Read <a href="https://www.jerolba.com/hashing-y-mapas/">this Spanish article</a> for a very interesting case where a customized redefinition of <code>hashCode()</code> fixed a poor performance issue.</p>
<h2>Hash Tables in the Java Collections Framework</h2>
<p>The Java Collections Framework uses hash tables in several classes:</p>
<ul>
<li><p>HashMap: The most widely used implementation of the Map interface, using a hash table internally.</p>
</li>
<li><p>HashSet: Implements the Set interface and is backed by a HashMap, using the hash table mechanism to ensure uniqueness of elements.</p>
</li>
</ul>
<p>The hash code determines the bucket or slot where the object is stored in these hash-based colllections.</p>
<h2>Equals() and hashCode()</h2>
<ul>
<li><p>If two objects are considered equal by the <code>equals()</code> method, they must have the same hash code as returned by <code>hashCode()</code>. This ensures that equal objects can be found in the same bucket in hash-based collections.</p>
</li>
<li><p>If two objects have the same hash code, they are not necessarily equal. Hash collisions can occur, so <code>equals()</code> is used as a second check to confirm actual equality.</p>
</li>
<li><p>If you override <code>equals()</code>, you must also override <code>hashCode()</code>. Failing to do so can lead to unexpected behavior in collections, such as not being able to retrieve objects that were added earlier.</p>
</li>
</ul>
<h2>Conclusion</h2>
<p>The data structure called <strong>Hash Table</strong> was briefly introduced in this article. The most used strategies for hash functions minimize collisions and improve performance. Finally, the relationship between <code>hashCode()</code> and <code>equals()</code> is crucial, as they are used together to ensure correct behavior in hash-based collections.</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Object Equality in Java]]></title><description><![CDATA[Introduction
The == operator is used to compare references, while the equals method is used to compare the contents of objects.
Comparison for predefined types
Primitive types
The comparison operator ]]></description><link>https://blog.programwithjr.com/mastering-object-equality-in-java</link><guid isPermaLink="true">https://blog.programwithjr.com/mastering-object-equality-in-java</guid><category><![CDATA[Java]]></category><category><![CDATA[Core Java]]></category><category><![CDATA[#equals]]></category><category><![CDATA[equals and hashcode]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Fri, 02 May 2025 09:57:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/d24a3254-d0b6-4811-89fb-d41925e0cfe1.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>The <code>==</code> operator is used to compare references, while the <code>equals</code> method is used to compare the contents of objects.</p>
<h2>Comparison for predefined types</h2>
<h3>Primitive types</h3>
<p>The comparison operator works with predefined types, such as integers, booleans, and characters:</p>
<pre><code class="language-java">int num = 2;
if (num == 2) {
    System.out.println("num equals two");
}
</code></pre>
<pre><code class="language-java">boolean gameIsOver = true;
if (gameIsOver) {  // Equivalent to: if (gameIsOver == true)
    System.out.println("The game is over");
}
</code></pre>
<h3>Strings</h3>
<p>However, there is a widely used predefined type that does not follow these rules: the <code>String</code> type.</p>
<pre><code class="language-java">String station = "SUMMER";
if (station.toLowerCase() == "summer") {  // INCORRECT!!
    System.out.println("It's summer");
}
</code></pre>
<p>This does not display the expected message.<br />The reason is that the <code>==</code> operator, when applied to strings, compares references, that is, memory locations. In principle, each variable is at a different memory location.</p>
<p>To compare the contents of strings, you should use the <code>equals</code> method defined in Java:</p>
<pre><code class="language-java">if (station.toLowerCase().equals("summer")) {
    System.out.println("It's summer");
}
</code></pre>
<h2>How to compare objects</h2>
<p>For objects of user-defined classes, you also use the <code>equals</code> method:</p>
<pre><code class="language-java">class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // getters and setters
}
</code></pre>
<pre><code class="language-java">Person person1 = new Person("Sara", 23);
Person person2 = new Person("Sara", 23);
if (person1.equals(person2)) {
    System.out.println("person1 and person2 are the same person");
}
</code></pre>
<p>The message is not displayed, so you can deduce that they are considered different people. This is because, by default, the equals method in the Object class only compares references, not the content of the fields.</p>
<p>The solution is to compare all the relevant fields:</p>
<pre><code class="language-java">if (person1.getName().equals(person2.getName()) &amp;&amp; person1.getAge() == person2.getAge()) {
    System.out.println("person1 and person2 are the same person");
}
</code></pre>
<p>To avoid repeating these conditions every time, you can define the <code>equals()</code> method:</p>
<pre><code class="language-java">public boolean equals(Person person) {
    if (person.getName().equals(this.getName()) &amp;&amp; person.getAge() == this.getAge()) {
        return true;
    } else {
        return false;
    }
}
</code></pre>
<h3>Overriding <code>equals()</code></h3>
<p>All classes created in Java inherit methods from the <code>Object</code> class. One of these methods is:</p>
<pre><code class="language-java">public boolean equals(Object object);
</code></pre>
<p>By default, <code>equals()</code> in <code>Object</code> checks if two references point to the same object (i.e., using <code>==</code>). Overriding <code>equals()</code> allows you to define equality based on the object's content:</p>
<pre><code class="language-java">@Override
public boolean equals(Object object) {
    // Explicit cast from Object to the type we're interested in
    Person person = (Person) object;
    return person.getName().equals(this.getName()) &amp;&amp; person.getAge() == this.getAge()) {
}
</code></pre>
<p>The <code>equals</code> method must return false when one of the objects is null:</p>
<pre><code class="language-java">@Override
public boolean equals(Object object) {
    if (object == null) {
        return false;
    }
    // ...
}
</code></pre>
<h2>Using <code>instanceof</code></h2>
<p>You can use <code>instanceof</code> to check the type before casting:</p>
<pre><code class="language-java">@Override
public boolean equals(Object object) {
    if (!(object instanceof Person)) {
        return false;
    }
    Person person = (Person) object;
    // ...
}
</code></pre>
<p>The null check is unnecessary because the <code>instanceof</code> operator returns false if its first operand is null.</p>
<h2>Using <code>Objects.equals()</code></h2>
<p>When comparing object fields, the previous approach is <strong>not null-safe</strong>. That means the condition will throw a <code>NullPointerException</code> if a field is null.<br />To avoid this, we use the <code>Objects.equals()</code> method, which returns false if either object is null and true if both are null:</p>
<pre><code class="language-java">@Override
public boolean equals(Object object) {
    if (!(object instanceof Person)) return false;
    Person person = (Person) object;
    return Objects.equals(name, person.name) &amp;&amp; age == person.age;
}
</code></pre>
<p>The disadvantage of using <code>Objects.equals()</code> is that it is not type-safe, so type checks are still necessary.</p>
<h2>Preserve the equality when subclassing</h2>
<p>The equals() method generated by many IDEs uses <strong>getClass()</strong> instead of <strong>instanceof</strong>.<br />When you use <strong>getClass()</strong>, you are performing a strict comparison. This means that derived classes or subclasses cannot be compared-they will not be considered equal to the parent class. If you want to compare subclasses with the parent class, you need to use the <strong>instanceof</strong> operator.</p>
<p>Some authors prefer using <strong>instanceof</strong> to allow subclasses to be compared, because inheritance is one of the fundamental properties of object-oriented programming. Additionally, symmetry is maintained, since <code>this.equals(employee)</code> gives the same result as <code>employee.equals(this)</code></p>
<p>Let's take a look at an example when comparing two objects of the same class hierarchy.</p>
<pre><code class="language-java">class Person {
    protected String name;
    protected int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        // Check for reference equality
        if (this == obj)
            return true;

        // if (obj == null || getClass() != obj.getClass())
        // return false;
        if (!(obj instanceof Person)) {
            return false;
        }

        // Field comparison
        Person other = (Person) obj;
        return getAge() == other.getAge() &amp;&amp; Objects.equals(getName(), other.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}
</code></pre>
<pre><code class="language-java">class Employee extends Person {

    public Employee(String name, int age) {
        super(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        // Check for reference equality
        if (this == obj)
            return true;

        // if (obj == null || getClass() != obj.getClass())
        if (!(obj instanceof Person))
            return false;

        // Field comparison
        Person other = (Person) obj;
        return getAge() == other.getAge() &amp;&amp; Objects.equals(getName(), other.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
</code></pre>
<pre><code class="language-java">import java.util.List;
import java.util.ArrayList;
import java.util.Objects;

public class SubclassComparison {
    public static void main(String[] args) {
        // List of objects of the parent class
        List&lt;Person&gt; personsList = new ArrayList&lt;&gt;();
        Person alice = new Person("Alice", 30);
        Person bob = new Person("Bob", 25);
        personsList.add(alice);
        personsList.add(bob);

        // List of objects of the subclass
        List&lt;Employee&gt; employeesList = new ArrayList&lt;&gt;();
        Employee aliceEmployee = new Employee("Alice", 30);
        Employee bobEmployee = new Employee("Bob", 25);
        employeesList.add(aliceEmployee);
        employeesList.add(bobEmployee);

        // Compare the lists
        boolean areEqual = personsList.equals(employeesList);
        System.out.println("Employee lists are equal: " + areEqual); 
    }
}
</code></pre>
<h2>HashCode</h2>
<p>The <strong>hashCode()</strong> method is used to generate a hash code for an object.<br />The hash code is a unique value that represents the object in hash-based collections.</p>
<p>Overriding <strong>hashCode()</strong> is crucial because it ensures that objects behave correctly when used in hash-based collections like <em>HashMap</em>, <em>HashSet</em>, and <em>Hashtable</em>.</p>
<h2>Records</h2>
<p>If you use a <strong>record</strong>, introduced in Java 16, the compiler implicitly creates the constructor, getters, <strong>equals()</strong>, <strong>hashCode()</strong>, and toString() methods.</p>
<pre><code class="language-java">record Person(String name, int age) { }
</code></pre>
<h2>Conclusion</h2>
<p>Understanding the difference between the == operator and the equals() method is essential.</p>
<p>The == operator compares object references, while equals() should be overridden to compare the actual content of objects.</p>
<p>When overriding equals(), <strong>always override hashCode()</strong> as well to ensure correct behavior in hash-based collections.</p>
<p>Using <strong>instanceof</strong> in your equals() implementation allows for greater flexibility and supports inheritance, which is a core principle of object-oriented programming.</p>
<p>For modern Java applications, <strong>records</strong> offer a concise way to create immutable data classes with proper equality and hashing behavior generated automatically by the compiler.</p>
]]></content:encoded></item><item><title><![CDATA[How to use an interface]]></title><description><![CDATA[Introduction
This article may seem too basic, but I decided to write it after seeing that many programmers do not know how to use interfaces in Java. This topic is related to design patterns in object]]></description><link>https://blog.programwithjr.com/how-to-use-an-interface</link><guid isPermaLink="true">https://blog.programwithjr.com/how-to-use-an-interface</guid><category><![CDATA[Java]]></category><category><![CDATA[interface]]></category><category><![CDATA[patterns]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Wed, 23 Apr 2025 15:29:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/a2b8a4a8-0eb3-4d0d-b8bd-4c92e9324020.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>This article may seem too basic, but I decided to write it after seeing that many programmers do not know how to use interfaces in Java. This topic is related to design patterns in object-oriented programming (OOP).</p>
<h2>An apparently simple class</h2>
<p>We all have seen code similar to this one:</p>
<pre><code class="language-java">enum EnergyPlan {
    PlanA, PlanB, PlanC
}
</code></pre>
<pre><code class="language-java">class EnergyCalculator {

    BigDecimal calculateEnergy(EnergyPlan plan) {
        if (plan == EnergyPlan.PlanA) {
            System.out.println("Calculating energy for Plan A");
            return new BigDecimal(100);
        } else if (plan == EnergyPlan.PlanB) {
            System.out.println("Calculating energy for Plan B");
            return new BigDecimal(300);
        } else if (plan == EnergyPlan.PlanC) {
            System.out.println("Calculating energy for Plan C");
            return new BigDecimal(400);
        }
        else {
            throw new IllegalArgumentException("Unknown plan");
        }
    }
}
</code></pre>
<p>An enumeration is used and the <code>EnergyCalculator</code> class has only one method, which is not hard to follow.</p>
<p>Although it's probably easier to read if a switch statement is used:</p>
<pre><code class="language-java">class EnergyCalculator {

    BigDecimal calculateEnergy(EnergyPlan plan) {
        switch (plan) {
            case PlanA:
                System.out.println("Calculating energy for Plan A");
                return new BigDecimal(100);
            case PlanB:
                System.out.println("Calculating energy for Plan B");
                return new BigDecimal(300);
            case PlanC:
                System.out.println("Calculating energy for Plan C");
                return new BigDecimal(400);
            default:
                throw new IllegalArgumentException("Unknown plan");
        }
    }
}
</code></pre>
<p>Starting from Java 14 a switch expression can be used:</p>
<pre><code class="language-java">class EnergyCalculator {

    BigDecimal calculateEnergy(EnergyPlan plan) {
        BigDecimal result = switch (plan) {
            case PlanA -&gt; {
                System.out.println("Calculating energy for Plan A");
                yield new BigDecimal(100);
            }
            case PlanB -&gt; {
                System.out.println("Calculating energy for Plan B");
                yield new BigDecimal(300);
            }
            case PlanC -&gt; {
                System.out.println("Calculating energy for Plan C");
                yield new BigDecimal(400);
            }
        };
        return result;
    }
}
</code></pre>
<h2>The problem</h2>
<p>You might be thinking: <em>So what? I don't see any issue.</em> 
And you're right...... until the logic for the different plans start to grow:</p>
<pre><code class="language-java">class EnergyCalculator {

    BigDecimal calculateEnergy(EnergyPlan plan) {
        BigDecimal result = switch (plan) {
            case PlanA -&gt; {
                // Step 1
                // Step 2
                // Step 3
                yield new BigDecimal(100);
            }
            case PlanB -&gt; {
                // Step 1
                // Step 2
                // Step 3
                yield new BigDecimal(300);
            }
            case PlanC -&gt; {
                // Step 1
                // Step 2
                // Step 3
                yield new BigDecimal(400);
            }
        };
        return result;
    }
}
</code></pre>
<p>Imagine that each step is different for each plan and you easily end up having a one-hundred line class. 
One week later, you have to add a new plan and in one month you have up to six different plans. </p>
<p>The number of lines is now three hundred and you have to maintain it. It's <strong>very hard to read</strong> and to modify. It's not an exaggeration, this has happened to me.</p>
<p>Precisely this is what we are referring to when we say that the traditional if/else or switch block <strong>is not scalable</strong>.</p>
<p>Some of you may be thinking: <em>But it's not too bad, since the logic is contained in methods from other classes</em>. Even in that case, <strong>a long method is hard to maintain.</strong>
Not to mention how you are going to test it. You have to mock all the classes that are involved in the logic. <strong>It's a mess.</strong></p>
<h2>The solution</h2>
<p>Instead of having a very big block for each case, wouldn't it be better to create a class per plan and execute the same method:</p>
<pre><code class="language-java">class EnergyCalculator {
    public BigDecimal calculateEnergy(EnergyPlan plan) {
        EnergyPlanStrategy strategy;
        switch (plan) {
            case PlanA -&gt; strategy = new PlanAStrategy();
            case PlanB -&gt; strategy = new PlanBStrategy();
            case PlanC -&gt; strategy = new PlanCStrategy();
            default -&gt; throw new IllegalArgumentException("Unknown plan: " + plan);
        }
        return strategy.calculateEnergy();
    }
}
</code></pre>
<p>A number of classes with the same <code>calculateEnergy()</code> method. Does this sound familiar? It's like <code>ArrayList</code> and <code>LinkedList</code> implementing the same <code>get()</code> method (see my previous article).</p>
<p>Exactly, they are different implementations of the same interface:</p>
<pre><code class="language-java">interface EnergyPlanStrategy {
    BigDecimal calculateEnergy();
}

// Implementations for each plan
class PlanAStrategy implements EnergyPlanStrategy {
    @Override
    public BigDecimal calculateEnergy() {
        // Steps 1, 2, 3
    }
}

class PlanBStrategy implements EnergyPlanStrategy {
    @Override
    public BigDecimal calculateEnergy() {
        // Steps 1, 2, 3
    }
}

class PlanCStrategy implements EnergyPlanStrategy {
    @Override
    public BigDecimal calculateEnergy() {
        // Steps 1, 2, 3
    }
}
</code></pre>
<p>This is the diagram for the Energy Plan Strategy Pattern:</p>
<pre><code class="language-mermaid">%% Title: Energy Plan Strategy Pattern
classDiagram
    title Energy Plan Strategy Pattern

    class EnergyPlanStrategy {
        &lt;&lt;interface&gt;&gt;
        +calculateEnergy(): BigDecimal
    }

    class PlanAStrategy {
        +calculateEnergy(): BigDecimal
    }
    class PlanBStrategy {
        +calculateEnergy(): BigDecimal
    }
    class PlanCStrategy {
        +calculateEnergy(): BigDecimal
    }

    EnergyPlanStrategy &lt;|.. PlanAStrategy
    EnergyPlanStrategy &lt;|.. PlanBStrategy
    EnergyPlanStrategy &lt;|.. PlanCStrategy
</code></pre>
<p>The logic is contained in the different implementations of the <code>EnergyPlanStrategy</code> interface. They are different classes, as a result the code is easier to read and easier to test.</p>
<p>If a plan must be added, only one class needs to be added and a single line inside the switch/case block.
We say this technique is scalable.</p>
<p>Notice we are not even using lambda expressions (see my article here) or any other feature introduced in Java 8. Except the new syntax for the switch/case block, this is all about <strong>using interfaces in a clever way</strong>.</p>
<h2>Formal Definition</h2>
<p>This technique is used so often that is a design pattern called <strong>Strategy Pattern</strong>. 
The main idea is to use interfaces to define a family of algorithms, encapsulate each one of them in a different class, and make them interchangeable.</p>
<h2>Disadvantages</h2>
<p>For complex logic, this pattern results in a <strong>more testable and maintainable code.</strong> This is a concise way of saying that <em>the code is easier to read and easier to test.</em></p>
<p>The main disadvantage is that the code is more verbose. Every time a plan (algorithm) is added, a new class implementing the interface must be added, in addition to the line inside the switch/case block.</p>
<h2>Summary</h2>
<p>The <strong>interface pattern</strong> defines behaviors through interfaces and provides concrete implementations via classes. 
Interfaces act as contracts that specify method/s to be implemented, enabling abstraction and decoupling between the definition and the implementation of behaviors. </p>
<p>This pattern enhances flexibility, scalability, and the ability to extend implementations without affecting client code (the <em>open to extension, closed to modification</em> principle).</p>
<p>It relies solely on interfaces and classes, promoting the principle of <em>program to an interface, not an implementation.</em> This allows multiple classes to implement the same interface, encouraging code reuse and maintainability.</p>
<p>As a secondary goal, the evolution of the switch/case block was shown.</p>
]]></content:encoded></item><item><title><![CDATA[What's in a List]]></title><description><![CDATA[Introduction
List is an interface in Java Collections that represents an ordered sequence of elements.
Features of a List:

Access elements by position (index).

Store duplicate elements, because a Se]]></description><link>https://blog.programwithjr.com/whats-in-a-list</link><guid isPermaLink="true">https://blog.programwithjr.com/whats-in-a-list</guid><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Thu, 17 Apr 2025 12:24:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/2b847c93-6ceb-4d96-beb7-ec6896b142cb.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p><strong>List</strong> is an interface in Java Collections that represents an ordered sequence of elements.</p>
<p>Features of a List:</p>
<ul>
<li><p>Access elements by position (index).</p>
</li>
<li><p>Store duplicate elements, because a Set does not store duplicates.</p>
</li>
<li><p>Insert or remove elements at any position.</p>
</li>
</ul>
<p>This is the canonical definition of a List in Java.</p>
<h2>The most common implementation</h2>
<p>List being an interface, the most used implementation is the <code>java.util.ArrayList</code> class:</p>
<pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;();
list.add("This");
list.add("is");
list.add("a");
list.add("list");
</code></pre>
<p>we can access elements by index:</p>
<pre><code class="language-java">String element = list.get(1);
System.out.println(element); // prints "is"
</code></pre>
<p>It is also possible to remove elements by index:</p>
<pre><code class="language-java">list.remove(2);
for (String element : list) {
    System.out.println(element);  // prints "This", "is", "list"
}
</code></pre>
<p>It is quite simple. It is like an array, but we do not have to worry about resizing it. The <strong>ArrayList</strong> class takes care of that. The notation is also different. We use <code>get()</code> instead of <code>[]</code> to access elements by index.</p>
<h2>List Methods</h2>
<p>Most of the methods are self-explanatory. The main ones are:</p>
<ul>
<li><p><code>add()</code>: adds an element to the end of the list.</p>
</li>
<li><p><code>remove()</code>: removes an element from the list.</p>
</li>
<li><p><code>get()</code>: returns the element at the specified index.</p>
</li>
<li><p><code>size()</code>: returns the number of elements in the list.</p>
</li>
<li><p><code>isEmpty()</code>: returns <code>true</code> if the list is empty, <code>false</code> otherwise.</p>
</li>
<li><p><code>contains()</code>: returns <code>true</code> if the list contains the specified element, <code>false</code> otherwise.</p>
</li>
<li><p><code>indexOf()</code>: returns the index of the first occurrence of the specified element in the list, or <code>-1</code> if the element is not found.</p>
</li>
<li><p><code>lastIndexOf()</code>: returns the index of the last occurrence of the specified element in the list, or <code>-1</code> if the element is not found.</p>
</li>
</ul>
<p>Two methods are going to be explained, because they are a bit confusing.</p>
<h3>add()</h3>
<p><code>add()</code> is an overloaded method. It has two versions:</p>
<pre><code class="language-java">list.add(element);
list.add(index, element);
</code></pre>
<p>The first version adds the element to the end of the list, while the second version adds the element at the specified index. The second one would have rather been called <code>insertAt()</code>.</p>
<h3>set()</h3>
<p><code>set(int index, E element)</code> replaces the element at the specified index with the given element. It return the element that was previously at the specified position.</p>
<ul>
<li><p>The list <strong>must have an element at the specified index</strong>, otherwise it throws an exception.</p>
</li>
<li><p>It changes the element in place, so it <strong>does not change the size of the list.</strong></p>
</li>
</ul>
<h2>The LinkedList class</h2>
<p>Why not use the <code>ArrayList</code> implementation always?</p>
<p>The <code>ArrayList</code> class is a good choice for most cases, in fact most of the programmers have only used that class when creating a List.</p>
<p>But there is one thing that the <code>ArrayList</code> class does not do very well: inserting and removing elements in random list positions. Why? Because every time an element is inserted or removed, the remaining elements starting from the modified position have to be shifted, since all the array elements must be stored in contiguous memory.</p>
<p>As a consequence, an <code>LinkedList</code> should be faster than an <code>ArrayList</code> for adding or removing elements in the middle of the list. Unless you have to use a cache memory, in which case you will prefer a list whose elements are contiguous in memory.</p>
<pre><code class="language-java">List&lt;String&gt; list = new LinkedList&lt;&gt;();
list.add("This");
list.add("is");
list.add("a");
list.add("list");
</code></pre>
<p>Since both classes implement the <code>List</code> interface, we can use them interchangeably.</p>
<p>Let's see how a simplified <code>LinkedList</code> looks like:</p>
<pre><code class="language-java">class LinkedList {
    private Node head = null;  // Start of the list
    private int size = 0;      // Number of nodes
    private int index = 0;
}

class Node {
    private String data;        // Element stored in this node
    private Node next = null;     // Link to the next node
    private Node previous = null; // Link to the previous node
}
</code></pre>
<p>As we can see, it is a doubly linked list. A node has three attributes: the data itself, and references to the next and previous nodes.</p>
<p>These nodes are not contiguous in memory. Therefore, when an element is inserted or removed, the remaining elements do not have to be shifted. A node has to modify only its two references, resulting in much faster operations.</p>
<pre><code class="language-mermaid">graph LR
    subgraph MyLinkedList [Linked List]
        A[10] --&gt; B[20]
        B --&gt; C[30]
    end
</code></pre>
<p>After removing 20:</p>
<pre><code class="language-mermaid">graph LR
    subgraph MyLinkedList [Linked List after removing Node B]
        A[10] --&gt; C[30]
        B[20]  
    end
</code></pre>
<h2>ArrayList vs LinkedList</h2>
<p>The <code>ArrayList</code> class is faster for adding and removing elements in the middle of the list, while the <code>LinkedList</code> class is faster for adding and removing elements at the beginning or end of the list.</p>
<p>Let's see an example for measuring the time it takes to add and remove elements in the middle of the list:</p>
<pre><code class="language-java">import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

public class ListInsertionBenchmark {
    public static void main(String[] args) {
        final int ELEMENT_COUNT = 10_000; // Number of insertions to test

        // Test ArrayList
        List&lt;Integer&gt; arrayList = new ArrayList&lt;&gt;();
        long arrayListTime = timeInsertInMiddle(arrayList, ELEMENT_COUNT);

        // Test LinkedList
        List&lt;Integer&gt; linkedList = new LinkedList&lt;&gt;();
        long linkedListTime = timeInsertInMiddle(linkedList, ELEMENT_COUNT);

        System.out.println("\nResults:");
        System.out.printf("ArrayList insertion time: %d ms\n", arrayListTime);
        System.out.printf("LinkedList insertion time: %d ms\n", linkedListTime);
    }

    private static long timeInsertInMiddle(List&lt;Integer&gt; list, int insertions) {
        // Pre-fill the list to avoid starting empty
        for (int i = 0; i &lt; 1_000_000; i++) {
            list.add(i);
        }

        long startTime = System.currentTimeMillis();
        for (int i = 0; i &lt; insertions; i++) {
            int middleIndex = list.size() / 2;
            list.add(middleIndex, i); // Insert at middle
        }
        long endTime = System.currentTimeMillis();

        return endTime - startTime;
    }
}
</code></pre>
<p>If we run this program, it turns out that the <code>LinkedList</code> insertion time is much greater than the <code>ArrayList</code> one, although all the insertions are done in the middle of the list.</p>
<p>It seems that the time it takes to traverse the list from head/tail to reach a middle index is higher for the <code>LinkedList</code>. This happens because the <code>ArrayList</code> data structure is optimized for shifting <strong>contiguous</strong> elements by using <code>System.arraycopy()</code>; whereas <strong>traversing all the nodes is slow</strong> because nodes are scattered in memory. Each pointer access can result in a memory <strong>cache miss</strong>, which makes the process even slower. In other words, insertion in a LinkedList <strong>without an iterator</strong> is a <strong>O(n)</strong> operation.</p>
<p><code>System.arraycopy()</code> copies memory blocks from one part of an array to another. It's a <strong>native method</strong>, that is, its core logic is implemented in a lower-level language like C (or C++) for performance reasons. If a traditional loop were used to copy every single list element, the traversing time would be much higher.</p>
<p><strong>ArrayList is faster due to contiguous memory and optimized block copying</strong>, not because it's a faster algorithm in terms of complexity.</p>
<p>The benchmark highlights that <strong>algorithmic complexity alone does not determine real-world performance.</strong> ArrayList’s optimized memory operations make it a strong contender even for middle insertions. We should profile our specific use case to make the most informed decision.</p>
<h2>The missing piece: ListIterator</h2>
<p>We said</p>
<blockquote>
<p>The <code>LinkedList</code> class is faster for adding and removing elements at the middle of the list.</p>
</blockquote>
<p>but the results obtained in the benchmark did not match that statement.</p>
<p>We can use a <strong>ListIterator</strong> and move it to a position <strong>once</strong> and then do many insertions/removals at that spot. In this way, we <strong>don't need to traverse the list each time.</strong></p>
<pre><code class="language-java">    public static void main(String[] args) {
        final int ELEMENT_COUNT_WITH_ITERATOR = 3000;

        long arrayListIteratorTime = timeInsertUsingAnIterator(arrayList, ELEMENT_COUNT_WITH_ITERATOR);

        long linkedListIteratorTime = timeInsertUsingAnIterator(linkedList, ELEMENT_COUNT_WITH_ITERATOR);
        // ArrayList vs LinkedList
        System.out.println("\nResults:");
        System.out.printf("ArrayList insertion time: %d ms\n", arrayListTime);
        System.out.printf("LinkedList insertion time: %d ms\n", linkedListTime);

        System.out.printf("ArrayList iterator insertion time: %d ms\n", arrayListIteratorTime);
        System.out.printf("LinkedList iterator insertion time: %d ms\n", linkedListIteratorTime);
    }

    private static long timeInsertUsingAnIterator(List&lt;Integer&gt; list, int insertions) {
        // Pre-fill the list to avoid starting empty
        for (int i = 0; i &lt; 10_000; i++) {
            list.add(i);
        }

        long startTime = System.currentTimeMillis();
        ListIterator&lt;Integer&gt; iterator = list.listIterator(5000);
        for (int i = 0; i &lt; insertions; i++) {
            iterator.add(i);
        }
        long endTime = System.currentTimeMillis();

        return endTime - startTime;
    }
}
</code></pre>
<p>The insertions time for the <code>LinkedList</code> is very close to zero, and it's much faster than the ones for the <code>ArrayList</code>.</p>
<p><strong>Multiple</strong> insertion and removals are faster when using a <code>LinkedList</code>, provided an iterator at the correct position is used. In these cases, insertion in a LinkedList is a <strong>O(1)</strong> operation.</p>
<p>A <code>LinkedList</code> is suitable for use cases where we need to add and remove elements at a known same position <strong>and</strong> we don't need to access elements by index often. Examples are undo/redo stacks and managing history.</p>
<p><code>LinkedList</code> implements both the <code>Queue</code> and <code>Deque</code> interfaces, which means that it is a good choice for use cases where we need to add and remove elements from both ends of the list.</p>
<h2>Conclusion</h2>
<p>The Java <code>List</code> is an interface with methods for adding, removing, and accessing elements. It has two different implementations: ArrayList and LinkedList.</p>
<p><code>ArrayList</code> offers excellent general-purpose performance, especially for random access and adding/removing at the end. <code>LinkedList</code> provides faster insertion and deletion if an <strong>iterator</strong> at the correct position is used. As always, the optimal choice depends on your application's specific needs and access patterns.</p>
]]></content:encoded></item><item><title><![CDATA[On the Collectors used in the Stream API]]></title><description><![CDATA[Introduction to Collectors
Collect is an extremely useful terminal operation to transform the elements of the stream into a different kind of result, like a List, a Set or a Map.
Java supports various built-in collectors via the Collectors class.
A v...]]></description><link>https://blog.programwithjr.com/on-the-collectors-used-in-the-stream-api</link><guid isPermaLink="true">https://blog.programwithjr.com/on-the-collectors-used-in-the-stream-api</guid><category><![CDATA[Java]]></category><category><![CDATA[Streams]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[collectors]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Wed, 26 Mar 2025 09:42:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743012810638/23baeb3f-bbf7-41a1-b1c8-f8a9e21a84be.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction-to-collectors">Introduction to Collectors</h2>
<p>Collect is an extremely useful terminal operation to transform the elements of the stream into a different kind of result, like a <code>List</code>, a <code>Set</code> or a <code>Map</code>.</p>
<p>Java supports various built-in collectors via the <code>Collectors</code> class.</p>
<p>A very common use case is to convert a list into another list, after filtering the elements.</p>
<pre><code class="lang-java">List&lt;Integer&gt; listOfNumbers = Arrays.asList(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>);
</code></pre>
<pre><code class="lang-java">List&lt;Integer&gt; listOfEvenNumbers = listOfNumbers.stream()
    .filter(n -&gt; n % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>)
    .collect(Collectors.toList());
</code></pre>
<h2 id="heading-formal-definition">Formal definition</h2>
<p>The official java doc for <strong>java.util.stream.Collector</strong> defines it as follows:</p>
<blockquote>
<p>A Collector is a mutable reduction operation that accumulates input elements into a mutable result container, optionally transforming the accumulated result into a final representation after all input elements have been processed.</p>
</blockquote>
<h3 id="heading-what-is-a-mutable-reduction-operation">What is a mutable reduction operation</h3>
<p>A mutable reduction operation, such as <strong>Stream.collect()</strong>, collects the stream elements into a mutable result container as it processes them. On the other hand, a non-mutable reduction operation, such as <strong>Stream.reduce()</strong> uses immutable result containers and as a result needs to create a new (instance of the) container at every intermediate step of reduction. This degrades performance.</p>
<h2 id="heading-how-a-collector-works">How a Collector works</h2>
<p>As explained above, a collector collects the elements of a stream into a mutable container. There are five steps to this process:</p>
<ul>
<li><p><strong>Step 1 - Supplier provides the mutable empty result container</strong> It is an instance of the <strong>Supplier</strong> functional interface which provides an instance of a Collection(or Map) to hold the collected elements.</p>
</li>
<li><p><strong>Step 2 - Accumulator adds individual elements into the result container</strong> It is an instance of the <strong>BiConsumer</strong> functional interface. It adds individual elements of stream encountered by it into the result container. This step is known as a <em>fold</em> in functional programming parlance.</p>
</li>
<li><p><strong>Step 3 - Combiner combines two partial results</strong> It is an instance of a <strong>BinaryOperator</strong> functional interface which combines two partial results returned by two separate groups of accumulations done in parallel.</p>
</li>
<li><p><strong>Step 4 - Optional Finisher to put the processed elements in a desired form</strong> It is an instance of a <strong>Function</strong> interface. If required, a Finisher can be used to map the collected elements in the result container to a different required form.</p>
</li>
<li><p><strong>Step 5 - Final Result</strong> The final collected elements are returned by the Collection in the result container i.e. Collection instance.</p>
</li>
</ul>
<p>A Collector consists of four different operations: a supplier, an accumulator, a combiner and a finisher.</p>
<h2 id="heading-the-collector-interface">The Collector Interface</h2>
<p>It is defined as follows:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Collector</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">A</span>, <span class="hljs-title">R</span>&gt;</span>
</code></pre>
<ul>
<li><p><strong>T</strong> is the element type being processed by the Stream.</p>
</li>
<li><p><strong>A</strong> is the type of the accumulated result container which keeps on getting elements (of type <strong>T</strong>) added throughout the <em>collecting</em> process.</p>
</li>
<li><p><strong>R</strong> is the type of the result container, or the collection, which is returned back as the final output by the collector.</p>
</li>
</ul>
<h2 id="heading-predefined-collectors">Predefined Collectors</h2>
<p>Java provides static methods in the <strong>java.util.stream.Collectors</strong> class for the most common mutable reduction operations.</p>
<h3 id="heading-joining">joining()</h3>
<p>To convert a list of numbers to a string, separated by commas:</p>
<pre><code class="lang-java">String numbersJoined = listOfNumbers.stream()
    .map(Object::toString)
    .collect(Collectors.joining(<span class="hljs-string">", "</span>));
</code></pre>
<h3 id="heading-summingint">summingInt()</h3>
<p>To sum the elements of a list:</p>
<pre><code class="lang-java"><span class="hljs-keyword">int</span> total = listOfNumbers.stream()
    .collect(Collectors.summingInt(Integer::intValue));
</code></pre>
<h3 id="heading-groupingby-and-partitioningby">groupingBy() and partitioningBy()</h3>
<p>Aggregations on the elements of a stream are quite common:</p>
<pre><code class="lang-java">Map&lt;String, List&lt;Employee&gt;&gt; employeesByDepartment = 
                 listOfEmployees.stream()
                 .collect(Collectors.groupingBy(Employee::getDepartment));
</code></pre>
<p>Partition is other common collector, which is used to partition elements based on a condition:</p>
<pre><code class="lang-java">Map&lt;Boolean, List&lt;Employee&gt;&gt; partitionedEmployees = 
   listOfEmployees.stream()
                  .collect(Collectors.partitioningBy(e -&gt; e.getDepartment() == CHOSEN_DEPARTMENT));

<span class="hljs-comment">// To get only the employees in the chosen department:</span>
List&lt;Employee&gt; employeesByDepartment = partitionedEmployees.get(<span class="hljs-keyword">true</span>);
</code></pre>
<h3 id="heading-count">count()</h3>
<p>For counting items in a list after a certain condition:</p>
<pre><code class="lang-java"><span class="hljs-keyword">long</span> countEvenNumbers = listOfNumbers.stream()
    .filter(n -&gt; n % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>)
    .count();
</code></pre>
<p>Other predefined collectors are <code>toSet()</code>, <code>toMap()</code>, <code>maxBy()</code>, <code>minBy()</code>, <code>reducing()</code>, <code>averaginInt()</code>, <code>counting()</code>, <code>mapping()</code></p>
<h2 id="heading-custom-collectors">Custom Collectors</h2>
<p>A new collector is created by using the <code>Collector.of()</code> method. It receives four parameters: a <em>supplier</em>, an <em>accumulator</em>, a <em>combiner</em> and a <em>finisher</em>.</p>
<p>For example, let's create a collector that prints the duplicates of each element separated by commas:</p>
<pre><code class="lang-java">Collector&lt;Integer, StringJoiner, String&gt; numberJoinerCollector = 
    Collector.of(
        () -&gt; <span class="hljs-keyword">new</span> StringJoiner(<span class="hljs-string">", "</span>),                         <span class="hljs-comment">// supplier</span>
        (sj, num) -&gt; sj.add(num.toString()),            <span class="hljs-comment">// accumulator</span>
        StringJoiner::merge,                                    <span class="hljs-comment">// combiner</span>
        StringJoiner::toString);                                <span class="hljs-comment">// finisher</span>

String result = listOfNumbers
    .stream()
    .collect(numberJoinerCollector);
</code></pre>
<p>Since strings in Java are immutable, a helper class like <code>StringJoiner</code> is needed to let the collector construct a string. The combiner knows how to merge two StringJoiners into one.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The definition of collectors was explained in detail in this article. After that, the most common predefined collectors were introduced with examples. Finally, how to create custom collectors, using the <code>Collector&lt;T, A, R&gt;</code> interface, was shown.</p>
]]></content:encoded></item><item><title><![CDATA[More on Streams]]></title><description><![CDATA[The streams were introduced in my previous article. This is the second article in the series.
Comparison-based stream operations
We will explain several common methods, some of them were mentioned in ]]></description><link>https://blog.programwithjr.com/more-on-streams</link><guid isPermaLink="true">https://blog.programwithjr.com/more-on-streams</guid><category><![CDATA[Java]]></category><category><![CDATA[stream Api]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Tue, 11 Mar 2025 01:14:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/823eff91-9200-4940-9a95-2d4fa4c92cb9.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The streams were introduced in my <a href="https://blog.programwithjr.com/introduction-to-streams">previous article</a>. This is the second article in the series.</p>
<h2>Comparison-based stream operations</h2>
<p>We will explain several common methods, some of them were mentioned in the previous article.</p>
<h3>sorted</h3>
<p>It sorts the elements of the stream based on the comparator provided.</p>
<pre><code class="language-java">List&lt;Employee&gt; listOfEmployeesSortedByName = listOfEmployees
    .stream()
    .sorted((e1, e2) -&gt; e1.getName().compareTo(e2.getName()))
    .collect(Collectors.toList());
</code></pre>
<h3>min and max</h3>
<pre><code class="language-java">var youngestEmployee = listOfEmployees
    .stream()
    .min((e1, e2) -&gt; e1.getAge() - e2.getAge())
    .orElseThrow(NoSuchElementException::new);
</code></pre>
<p>Defining the comparison can be avoided by using <code>Comparator.comparing()</code>:</p>
<pre><code class="language-java">var oldestEmployee = listOfEmployees
    .stream()
    .max(Comparator.comparing(Employee::getAge))
    .orElseThrow(NoSuchElementException::new);
</code></pre>
<h3>distinct</h3>
<p>It does not take any arguments and returns a stream with distinct elements, eliminating duplicates. It uses the <code>equals()</code> method to decide whether two elements are equal. A common pattern is to use Sets to remove duplicates. <code>distinct()</code> achieves the same result in a more elegant way.</p>
<pre><code class="language-java">List&lt;Integer&gt; listOfDistinctNumbers = 
Arrays.asList(1, 2, 3, 4, 5, 1, 2, 6, 7, 3)
    .stream()
    .distinct()
    .collect(Collectors.toList());
</code></pre>
<h3>allMatch, anyMatch and noneMatch</h3>
<p>These operations are used to check if all, any or none of the elements in the stream match a certain condition. They take a predicate and return a boolean. The processing is stopped as soon as the answer is determined. This technique, also used by the Java logical operators, is called <strong>short-circuiting</strong>:</p>
<pre><code class="language-java">boolean allEven = listOfNumbers.stream()
                     .allMatch(n -&gt; n % 2 == 0);
boolean atLeastOneEven = listOfNumbers.stream()
                     .anyMatch(n -&gt; n % 2 == 0);
boolean noneEven = listOfNumbers.stream()
                     .noneMatch(n -&gt; n % 2 == 0);
</code></pre>
<h2>Stream Specializations</h2>
<p>We worked with <code>Stream&lt;T&gt;</code> so far. But there are other stream types, which are used in specific situations. The most used ones are:</p>
<ul>
<li><p><code>IntStream</code></p>
</li>
<li><p><code>LongStream</code></p>
</li>
<li><p><code>DoubleStream</code></p>
</li>
</ul>
<p>These specialized streams are used to perform operations on primitive types. They extend <code>BaseStream&lt;T&gt;</code> type, not <code>Stream&lt;T&gt;</code>.</p>
<pre><code class="language-java">IntStream extends BaseStream&lt;Integer&gt;
LongStream extends BaseStream&lt;Long&gt;
DoubleStream extends BaseStream&lt;Double&gt;
Stream&lt;T&gt; extends BaseStream&lt;T&gt;
</code></pre>
<p>To create a specialized stream, we use the static factory method <code>of()</code> of the corresponding type.</p>
<pre><code class="language-java">IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
LongStream longStream = LongStream.of(1L, 2L, 3L, 4L, 5L);
DoubleStream doubleStream = DoubleStream.of(1.0, 2.0, 3.0, 4.0, 5.0);
</code></pre>
<h2>Map variants: mapToInt, mapToLong and MapToDouble</h2>
<p>The <code>map()</code> operation, as explained in the previous article, returns a Stream type. But when dealing with numerical data to achieve statistics results, returning a number is more convenient.</p>
<p>A default value is not required for the <code>sum()</code> operation on an <strong>IntStream</strong>, because sum() returns 0 for an empty stream. Therefore, sum() is a <strong>terminal</strong> operation.</p>
<pre><code class="language-java">List&lt;Integer&gt; listOfNumbers = Arrays.asList(1, 2, 3, 4, 5);
</code></pre>
<pre><code class="language-java">int sum = listOfNumbers
    .stream()
    .mapToInt(n -&gt; n)
    .sum();
</code></pre>
<p>Unlike <code>sum()</code>, the <code>average()</code> method returns an <code>OptionalDouble</code> to account for empty streams. Attempting to assign this directly to a double without handling the empty case will result in a compilation error. Other methods with a similar behavior -they do not return a primitive value- are <code>min()</code> and <code>max()</code>.</p>
<pre><code class="language-java">OptionalInt optionalMinimum = listOfNumbers
    .stream()
    .mapToInt(Integer::intValue)
    .min();
</code></pre>
<p>There are three possible solutions:</p>
<ul>
<li><p>Use the <code>orElse()</code> method to provide a default value.</p>
</li>
<li><p>Use the <code>orElseThrow()</code> method to throw an explicit error.</p>
</li>
<li><p>Use <code>getAsDouble()</code> if we assume the list will never be empty.</p>
</li>
</ul>
<p>Notice the two first methods are part of the <code>Optional&lt;T&gt;</code> API.</p>
<pre><code class="language-java">int minimum = listOfNumbers
    .stream()
    .mapToInt(Integer::intValue)  // Convert to IntStream
    .min()
    .orElse(0);
</code></pre>
<pre><code class="language-java">double average = listOfNumbers
    .stream()
    .mapToInt(Integer::intValue)  // Convert to IntStream
    .average()                    // Convert to OptionalDouble
    .orElseThrow(() -&gt; new IllegalArgumentException("List is empty"));
</code></pre>
<pre><code class="language-java">double average = listOfNumbers
    .stream()
    .mapToDouble(Integer::intValue)  
    .average()     // Convert to OptionalDouble 
    .getAsDouble();
</code></pre>
<h2>Statistics</h2>
<p>The <code>summaryStatistics()</code> method provides combined statistics like count, sum, min, average, and max.</p>
<pre><code class="language-java">IntSummaryStatistics stats = listOfNumbers
    .stream()
    .mapToInt(Integer::intValue)
    .summaryStatistics();

System.out.println("Count: " + stats.getCount());
System.out.println("Sum: " + stats.getSum());
System.out.println("Min: " + stats.getMin());
System.out.println("Max: " + stats.getMax());
System.out.println("Average: " + stats.getAverage());
</code></pre>
<h2>File operations</h2>
<p>Streams can also be used in file operations. For example, to read a file line by line and print those lines:</p>
<pre><code class="language-java">Stream&lt;String&gt; lines = Files.lines(Paths.get("file.txt"));
lines.forEach(System.out::println);
</code></pre>
<h2>Improvements in Java 9</h2>
<p>We will explore new methods like <code>takeWhile</code> and <code>dropWhile</code> that are used to perform operations on infinite streams.</p>
<pre><code class="language-java">Stream&lt;Integer&gt; infiniteStream = Stream.iterate(1, n -&gt; n + 1);

List&lt;Integer&gt; listOfNaturalNumbers = infiniteStream
    .takeWhile(n -&gt; n &lt;= 10)
    .map(x -&gt; x * x)
    .forEach(System.out::println);  
    // Prints 1, 4, 9, 16, 25, 36, 49, 64, 81, 100
</code></pre>
<p>In that example, using <code>filter()</code> instead of <code>takeWhile()</code> yields the same result. But the two methods opperates differently: <code>takeWhile()</code> stops processing as soon as the predicate is false, whereas <code>filter</code> evaluates the entire stream.</p>
<p><code>dropWhile()</code> is the opposite of <code>takeWhile()</code>. Instead of taking elements while a condition is true, <code>dropWhile</code> skips elements while the condition is true and starts returning elements when the condition becomes false. </p>
<p>These two methods already existed in the <strong>Scala</strong> and <strong>Kotlin</strong> APIs, but not in Java.</p>
]]></content:encoded></item><item><title><![CDATA[Introduction to Streams]]></title><description><![CDATA[Introduction to Streams
Streams are a sequence of elements that can be processed in a lazy way.
The Stream API is a feature introduced in version 8 of the Java platform that provides an efficient way ]]></description><link>https://blog.programwithjr.com/introduction-to-streams</link><guid isPermaLink="true">https://blog.programwithjr.com/introduction-to-streams</guid><category><![CDATA[Java]]></category><category><![CDATA[Streams]]></category><category><![CDATA[#declarative-pipeline]]></category><category><![CDATA[java development]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Sun, 02 Mar 2025 01:42:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/90b6941e-d101-4d4b-b155-fadc2c77373e.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction to Streams</h2>
<p>Streams are a sequence of elements that can be processed in a lazy way.</p>
<p>The Stream API is a feature introduced in version 8 of the Java platform that provides an efficient way to process collections. In Java 9, several improvements were made.</p>
<p>The Stream API is based on the concept of a pipeline of operations that can be applied to a stream of elements. This pipeline can be divided in three parts:</p>
<ul>
<li><p>Stream creation</p>
</li>
<li><p>Intermediate operations</p>
</li>
<li><p>Terminal operations</p>
</li>
</ul>
<p>A stream pipeline consists of a stream source, followed by zero or more intermediate operations, and finally a terminal operation. Notice that the terminal operation is the only one that returns a value.</p>
<p>Example of a stream pipeline without any intermediate operation:</p>
<pre><code class="language-java">streamOfEmployees
   .foreach(e -&gt; System.out.println(Employee::getName));
</code></pre>
<p>That was the formal definition of a stream. In practice, it can replace many loops, resulting in a much more readable and less error-prone code.</p>
<pre><code class="language-java">public List&lt;Integer&gt; getEvenNumbers(List&lt;Integer&gt; listOfNumbers) {
    List&lt;Integer&gt; listOfEvenNumbers = new ArrayList&lt;&gt;();
    for (Integer number : listOfNumbers) {
        if (number % 2 == 0) {
            listOfEvenNumbers.add(number);
        }
    }
    return listOfEvenNumbers;
}
</code></pre>
<p>Using streams:</p>
<pre><code class="language-java">public List&lt;Integer&gt; getEvenNumbers(List&lt;Integer&gt; listOfNumbers) {
    return listOfNumbers
        .stream()
        .filter(n -&gt; n % 2 == 0)
        .collect(Collectors.toList());
}
</code></pre>
<p>This is called a <strong>declarative way</strong> of writing code, because we are writing what result we want to achieve, without worrying about how to do it.</p>
<h2>Stream creation</h2>
<p>A stream can be created from an array or a collection.</p>
<pre><code class="language-java">private Employee[] employees = {
    new Employee("Jason", 30),
    new Employee("Maria", 32),
};

var streamOfEmployees = Stream.of(employees)
</code></pre>
<pre><code class="language-java">private List&lt;Employee&gt; employeesList = Arrays.asList(employees);

var streamOfEmployees = employeesList.stream()
</code></pre>
<p>We can use factory methods to create streams.</p>
<pre><code class="language-java">var streamOfIntegers = Stream.of(1, 2, 3, 4, 5)
</code></pre>
<pre><code class="language-java">var streamOfEmployees = Stream.of(
    new Employee("Jason", 30),
    new Employee("Maria", 32)
)
</code></pre>
<p>or using <code>Stream.builder()</code></p>
<pre><code class="language-java">Stream.Builder&lt;Employee&gt; streamBuilder = Stream.builder();
streamBuilder.accept(new Employee("Jason", 30));
streamBuilder.accept(new Employee("Maria", 32));
var streamOfEmployees = streamBuilder.build();
</code></pre>
<h2>Stream operations</h2>
<h3>forEach</h3>
<p>It is used to perform an action by calling the supplied transformation (lambda expression) on each element of the stream.</p>
<pre><code class="language-java">streamOfEmployees.forEach(e -&gt; e.getName());
</code></pre>
<p><strong>forEach() is a terminal operation</strong>.</p>
<h3>map</h3>
<p>It produces a new stream whose elements are the results of applying the given function to the elements of an existing stream.</p>
<pre><code class="language-java">var streamOfNames = streamOfEmployees
    .map(Employee::getName)      // or .map(e -&gt; e.getName())
    .collect(Collectors.toList());
</code></pre>
<p>Notices map is an intermediate operation, therefore we have to use a Collector after the transformation.</p>
<h3>filter</h3>
<p>It is similar to map but it filters the elements of the stream.</p>
<pre><code class="language-java">var streamOfNames = streamOfEmployeesInTheirThirties
    .filter(e -&gt; e != null)
    .filter(e -&gt; e.getAge() &gt;= 30)
    .collect(Collectors.toList());
</code></pre>
<h3>findFirst</h3>
<p>It returns an Optional containing the first element of the stream.</p>
<pre><code class="language-java">var employee = streamOfEmployees
    .map(employeeRepository::findById)
    .findFirst()
    .orElse(null);
</code></pre>
<p><strong>findFirst() is a terminal operation</strong>.</p>
<h3>flatMap</h3>
<p>It is similar to map but it flattens the elements of the stream. An example is converting a list of lists to a list of elements.</p>
<pre><code class="language-java">var ListOfNames = listOfEmployees
    .stream()
    // .map(Employee::getName)
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
</code></pre>
<h3>Other stream operations</h3>
<p>The following ones are only mentioned because they are very common. Their names are self explanatory:</p>
<ul>
<li><p><code>distinct()</code></p>
</li>
<li><p><code>sorted()</code></p>
</li>
<li><p><code>limit()</code></p>
</li>
<li><p><code>skip()</code></p>
</li>
<li><p><code>peek()</code></p>
</li>
<li><p><code>anyMatch()</code></p>
</li>
<li><p><code>allMatch()</code></p>
</li>
<li><p><code>noneMatch()</code></p>
</li>
<li><p><code>min()</code></p>
</li>
<li><p><code>max()</code></p>
</li>
</ul>
<h2>Terminal operations</h2>
<h3>count</h3>
<p>It returns the number of elements in the stream.</p>
<pre><code class="language-java">var numberOfEmployees = streamOfEmployees.count();
</code></pre>
<h3>reduce</h3>
<p>It reduces the stream to a single value.</p>
<pre><code class="language-java">var sumOfAges = streamOfEmployees
    .map(Employee::getAge)
    .reduce(0, Integer::sum);
</code></pre>
<p>Unlike other languages, <code>reduce</code> must receive a starting value.</p>
<p>A <strong>reduction operation</strong>, also called a fold, takes a sequence of elements and combines them into a single value by repeated applications of a combining operation. Other reduction operations are <strong>findFirst()</strong>, <strong>min()</strong> and <strong>max()</strong>.</p>
<pre><code class="language-java">var listOfNumber = List.of(1, 2, 3, 4, 5);

var sumOfNumbers = listOfNumber
    .stream()
    .reduce(0, Integer::sum);
</code></pre>
<p>or</p>
<pre><code class="language-java">var sumOfNumbers = listOfNumber
    .mapToInt(Integer::intValue)
    .sum();
</code></pre>
<h3>collect</h3>
<p>It is used to collect the elements of the stream into a container.</p>
<p>The strategy for this operation is provided via the <code>Collector</code> interface. There are several implementations of this interface, but the most common ones are the ones related to the three collection types:</p>
<ul>
<li><p><code>Collectors.toList()</code></p>
</li>
<li><p><code>Collectors.toSet()</code></p>
</li>
<li><p><code>Collectors.toMap()</code></p>
</li>
</ul>
<h3>toArray</h3>
<p>It returns an array containing the elements of the stream.</p>
<pre><code class="language-java">Employee[] ArrayOfEmployees = streamOfEmployees
    .toArray(Employee[]::new);
</code></pre>
<h2>Lazy evaluation</h2>
<p>In the beginning of the article we mentioned that the Stream API is lazy. This means that the stream pipeline is not executed until the terminal operation is called.</p>
<p>Why should we care? Let's see an example.</p>
<pre><code class="language-java">Stream&lt;Integer&gt; infiniteStream = Stream.iterate(0, n -&gt; n + 1);

List&lt;Integer&gt; listOfNaturalNumbers = infiniteStream
    .skip(3)
    .limit(10)
    .collect(Collectors.toList());
</code></pre>
<pre><code class="language-java">System.out.println(listOfNaturalNumbers);
</code></pre>
<p>The output is <code>[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]</code>.</p>
<p>The stream pipeline above will be executed only when the terminal operation is called. So <strong>all intermediate operations are lazy</strong>. This technique allows computations on finite streams to be completed in finite time. In other words, the evaluation of the functions is separated from the description of the transformation. This is the definition of lazy evaluation.</p>
<p>One of the most important characteristics of the streams is that they allow for <strong>significant optimizations through lazy evaluations</strong>.</p>
<h2>Parallel Streams</h2>
<p>Parallel streams are streams that are executed in parallel.</p>
<pre><code class="language-java">Stream&lt;Integer&gt; parallelStream = Stream.of(1, 2, 3, 4, 5)
    .parallel()
    .map(n -&gt; n * n);
</code></pre>
<p>As is the case when writing multi-threaded code, we need to be aware of a few things while using parallel streams:</p>
<ul>
<li><p>We need to ensure that the code is thread-safe. Take special care if the operations performed in parallel modify shared data.</p>
</li>
<li><p>We should not use parallel streams if the order in which operations are performed or the order returned in the output stream matters. For example, operations like findFirst() may generate different results in the case of parallel streams.</p>
</li>
<li><p>Also, we should ensure that it’s worth making the code execute in parallel. Understanding the performance characteristics of the operation in particular, but also of the system as a whole, is naturally very important.</p>
</li>
</ul>
<h2>Infinite Streams</h2>
<p>Also called unbounded streams, infinite streams are used to perform operations while the elements are still being generated. However, when using <em>map</em>, all the elements are already populated.</p>
<p>There are two ways to generate infinite streams:</p>
<h3>generate</h3>
<pre><code class="language-java">// Print ten random numbers
Stream.generate(Math::random)
    .limit(10)
    .forEach(System.out::println);
</code></pre>
<h3>iterate</h3>
<p>It takes an initial value, called the seed and a function that generates the next element using the previous value. <em>iterate()</em> is statefull, therefore it may not be useful in parallel streams:</p>
<pre><code class="language-java">Stream&lt;Integer&gt; evenNumbersStream = Stream.iterate(2, i -&gt; i * 2)
</code></pre>
<pre><code class="language-java">public getFirstEvenNumbers(int size) {
    return Stream.iterate(2, i -&gt; i * 2) // evenNumbersStream 
        .limit(size)
        .collect(Collectors.toList());
}
</code></pre>
<p><em>limit()</em> is the terminating condition.</p>
<h2>Summary</h2>
<p>The motivations behind Java streams were explained and several examples were presented. Several of the most common transformation were explained or mentioned.</p>
<p>The lazy evaluation technique was explained, which is used by many methods of the Stream API and allows to perform operations on infinite streams in a finite time. Parallel streams were created, which are streams that are executed in parallel.</p>
<p>The stream API is a powerful tool that can be used to perform operations on collections in a declarative way. It is remarkable change for any Java programmer.</p>
]]></content:encoded></item><item><title><![CDATA[An Introduction to Java Records for Beginners]]></title><description><![CDATA[Introduction
Java Records are a special kind of class introduced in Java 14, established as a standard feature in Java 16.
They are designed to encapsulate data, generating private final fields, an all-args constructor and the necessary methods for a...]]></description><link>https://blog.programwithjr.com/an-introduction-to-java-records-for-beginners</link><guid isPermaLink="true">https://blog.programwithjr.com/an-introduction-to-java-records-for-beginners</guid><category><![CDATA[Java]]></category><category><![CDATA[Records]]></category><category><![CDATA[jpa]]></category><category><![CDATA[class]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Wed, 19 Feb 2025 13:12:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740955482874/e6d8b48e-4967-4443-913d-61d7a9dd4b62.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Java Records are a special kind of class introduced in Java 14, established as a standard feature in Java 16.</p>
<p>They are designed to encapsulate data, generating <strong>private final fields</strong>, an all-args constructor and the necessary methods for any regular class: public getters or accessor method, equals(), hashCode() and toString(). Setters are not generated, because the data are immutable.</p>
<p>Records extend the <code>java.lang.Record</code> class, therefore they cannot extend any other class. And they can't be extended -they are final classes-.</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{ }
</code></pre>
<p>is equivalent to:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> age;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">name</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> name; }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">age</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> age; }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// Implementation </span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">equals</span><span class="hljs-params">(Object o)</span> </span>{
        <span class="hljs-comment">// Implementation </span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">hashCode</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// Implementation </span>
    }
}
</code></pre>
<p>As we can see, records take out the verbosity of traditional Java classes.</p>
<p>Although IDEs can automatically generate these methods, the class has to be updated every time a new field is added.</p>
<h2 id="heading-immutable-data">Immutable Data</h2>
<p>Record fields are immutable, which means that once created, they cannot be changed. Using the Person record declared above:</p>
<pre><code class="lang-java">Person person1 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Jose"</span>, <span class="hljs-number">30</span>);
</code></pre>
<p>The following code will cause a compilation error:</p>
<pre><code class="lang-java">person1.age = <span class="hljs-number">22</span>;
</code></pre>
<p>This immutability makes it easier to reason about the state of the objects and makes testing easier. However, this rule only applies to scalar fields. If there is a non-primitive or mutable field, its element can be modified:</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, List&lt;String&gt; friends)</span> </span>{ }
</code></pre>
<p>Elements of the <code>friends</code> list can be modified.</p>
<h2 id="heading-constructors">Constructors</h2>
<p>The all-arguments constructor is generated as shown above. It's also called the <code>canonical constructor</code>.</p>
<p>The explicit constructor is called <code>compact constructor</code>, and it allows developers to add custom logic during object initialization. A common use case is implementing validation rules.</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
    <span class="hljs-comment">// Unlike a class constructor, there is no a parameter list. </span>
    <span class="hljs-keyword">public</span> Person {
        Objects.requireNonNull(name);
        Objects.requireNonNull(age);
        <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">0</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Age must be a positive number."</span>);
        }
    }
}
</code></pre>
<p>Records can have a <strong>default constructor</strong> that initializes all components to their default values. This must delegate to the canonical constructor:</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{ 
    <span class="hljs-keyword">public</span> Person {
        <span class="hljs-comment">// call to the canonical constructor</span>
        <span class="hljs-keyword">this</span>(<span class="hljs-string">"Jose"</span>, <span class="hljs-number">33</span>);
    }
}

<span class="hljs-comment">// Usage</span>
Person person = <span class="hljs-keyword">new</span> Person();  <span class="hljs-comment">// name = "Jose", age = 33</span>
</code></pre>
<p><strong>Custom constructors</strong> can also be created by mixing the canonical constructor and default constructors.</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Person</span><span class="hljs-params">(<span class="hljs-keyword">int</span> age)</span> </span>{
        <span class="hljs-keyword">this</span>(<span class="hljs-string">"Jose"</span>, age);
    }
}

<span class="hljs-comment">// Usage</span>
Person person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Philip"</span>, <span class="hljs-number">52</span>)
Person person = <span class="hljs-keyword">new</span> Person(<span class="hljs-number">33</span>);  <span class="hljs-comment">// name = "Jose", age = 33</span>
</code></pre>
<p>This mimics the behaviour of languages thas has default values for their constructor parameters.</p>
<h2 id="heading-accessing-records-components">Accessing Records Components</h2>
<p>The dot notation is used, as in any other class, but followed by the field name.</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{ }
Person person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Jose"</span>, <span class="hljs-number">33</span>);
String name = person.name();
<span class="hljs-keyword">int</span> age = person.age();
</code></pre>
<p>The parentheses indicate that a getter method is being called.</p>
<h2 id="heading-overriding-methods">Overriding Methods</h2>
<p>The <code>toString</code>, <code>equals</code> and <code>hashCode</code> methods can be overridden.</p>
<h2 id="heading-implementing-methods-inside-records">Implementing Methods inside Records</h2>
<p>As with regular classes, static variables and methods can be defined inside records.</p>
<p>For example, something very close to a factory method can be achieved</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> Person <span class="hljs-title">withName</span><span class="hljs-params">(String name)</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Person(name, age);
    }
}

<span class="hljs-comment">// Usage</span>
Person person = person.withName(<span class="hljs-string">"Jose"</span>);
Person otherPerson = person.withName(<span class="hljs-string">"Philip"</span>);
</code></pre>
<p>or a validation method</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isAdult</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> age &gt;= <span class="hljs-number">18</span>;
    }
}

<span class="hljs-comment">// Usage</span>
Person person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Jose"</span>, <span class="hljs-number">33</span>);
<span class="hljs-keyword">boolean</span> isAdult = person.isAdult(); <span class="hljs-comment">// true</span>
</code></pre>
<h2 id="heading-how-to-ensure-that-records-are-immutable">How to ensure that Records are immutable</h2>
<p>Use defensive copies</p>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Person</span><span class="hljs-params">(String name, List&lt;String&gt; friends)</span> </span>{ }

List&lt;String&gt; friends = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
Person person1 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Jose"</span>, friends);
friends.add(<span class="hljs-string">"Philip"</span>);
friends.add(<span class="hljs-string">"Steve"</span>);

Person person2 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Jose"</span>, List.copyOf(friends);
person.friends().add(<span class="hljs-string">"Mafalda"</span>);
</code></pre>
<h2 id="heading-when-to-use-records">When to use Records</h2>
<p>Use records for simple data carriers where immutability is required. For example, to represent configuration settings or for Data Transfer Objects (DTO) in RESTful services.</p>
<h2 id="heading-disadvantages-of-records">Disadvantages of Records</h2>
<ul>
<li><p>Records are final, which means they cannot be extended. This might be a limitation to use some Java frameworks.</p>
</li>
<li><p>The mixture of traditional classes and records is a bit confusing, since the getters do not use the same notation.</p>
</li>
<li><p>Being all the fields final might not be what we want in some cases. In languages like Kotlin, you can choose if a given field is going to be immutable:</p>
</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-comment">// age is a mutable field and name is immutable</span>
<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span></span>(<span class="hljs-keyword">val</span> name: String, <span class="hljs-keyword">var</span> age: <span class="hljs-built_in">Int</span>)
</code></pre>
<h2 id="heading-using-records-with-jpa">Using Records with JPA</h2>
<p>Entities are classes that are mapped to a database table. In popular JPA providers like Hibernate, entities are created and managed using proxies. Proxies are classes that extend the entity class, relying on the entity to have a no-args constructor and setters. Since records do not have setters and are final, they can't be used as entities.</p>
<p>However, starting with version 6.2, Hibernate supports record classes as embeddables.</p>
<pre><code class="lang-java"><span class="hljs-meta">@Embeddable</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> record <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{ }
</code></pre>
<p>This annotation tells the persistence provider that this class can be embedded into entity objects.</p>
<pre><code class="lang-java"><span class="hljs-meta">@Entity</span> 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{

    <span class="hljs-meta">@Id</span>
    <span class="hljs-meta">@GeneratedValue</span>
    <span class="hljs-keyword">private</span> Long id;

    <span class="hljs-meta">@Embedded</span>
    <span class="hljs-keyword">private</span> Person person;

    <span class="hljs-keyword">private</span> String email;
    ................
}
</code></pre>
<p>Take into account that the information represented by the record is immutable.</p>
<pre><code class="lang-java">EntityManager entityManager = emFactory.createEntityManager();

User user = entityManager.find(User.class, userId);
<span class="hljs-comment">// user.person.name and user.person.age are immutable</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<ul>
<li><p>Java records make data class construction much easier than traditional POJOs, resulting in a much more readable code.  </p>
</li>
<li><p>The syntax for records contructors is different from regular classes.</p>
</li>
<li><p>All the record member fields are immutable, but be careful when dealing with non-primitive data types whose elements might be modified. </p>
</li>
<li><p>Records could not be used as entities, but this has changed in recent JPA versions.</p>
</li>
</ul>
<h2 id="heading-bibliography">Bibliography</h2>
<ul>
<li><p><a target="_blank" href="https://reflectoring.io/beginner-friendly-guide-to-java-records/">https://reflectoring.io/beginner-friendly-guide-to-java-records/</a></p>
</li>
<li><p><a target="_blank" href="https://www.baeldung.com/java-record-keyword">https://www.baeldung.com/java-record-keyword</a></p>
</li>
<li><p><a target="_blank" href="https://thorben-janssen.com/java-records-embeddables-hibernate/">https://thorben-janssen.com/java-records-embeddables-hibernate/</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Suppliers and Lazy Evaluation]]></title><description><![CDATA[Introduction
In Java, a Supplier is a functional interface introduced in Java 8 as part of the functional programming API, as explained in my previous article.
It is an interface that takes no argumen]]></description><link>https://blog.programwithjr.com/suppliers-and-lazy-evaluation</link><guid isPermaLink="true">https://blog.programwithjr.com/suppliers-and-lazy-evaluation</guid><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Wed, 12 Feb 2025 13:30:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/c8d80c7c-d0f4-435e-aa8a-2447e766985d.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>In Java, a Supplier is a functional interface introduced in Java 8 as part of the functional programming API, as explained in my previous article.</p>
<p>It is an interface that takes no arguments and produces a result of a specific type. Its abstract method is called get().</p>
<pre><code class="language-java">@FunctionalInterface 
public interface Supplier&lt;T&gt; { 
    T get();
}
</code></pre>
<p><strong>Usage:</strong></p>
<pre><code class="language-java">Supplier&lt;Double&gt; randomSupplier = () -&gt; Math.random();
Double randomValue = randomSupplier.get();
</code></pre>
<p>But when is providing a value without taking any input useful?</p>
<h2>Factory methods</h2>
<pre><code class="language-java">public interface Shape {
   void draw();
}
</code></pre>
<pre><code class="language-java">public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}
</code></pre>
<p>Factory pattern using Supplier:</p>
<pre><code class="language-java">final static Map&lt;String, Supplier&lt;Shape&gt;&gt; map = new HashMap&lt;&gt;();
static {
    map.put("circle", () -&gt; new Circle());  
    map.put("rectangle", () -&gt; new Rectangle());
}
</code></pre>
<p>The whole factory class is:</p>
<pre><code class="language-java">public class ShapeFactory {
    final static Map&lt;String, Supplier&lt;Shape&gt;&gt; map = new HashMap&lt;&gt;();
    static {
        map.put("circle", Circle::new);
        map.put("rectangle", Rectangle::new);
    }

    public Shape getShape(String shapeType) {
        Supplier&lt;Shape&gt; shape = map.get(shapeType.toLowerCase());
        if (shape != null) {
            return shape.get();
        }
        throw new IllegalArgumentException("Invalid shape type: " + shapeType.toLowerCase());
    }
}
</code></pre>
<p>The drawback of this technique is that it does not scale well if the factory method <code>getShape</code> needs to take multiple arguments to pass on to the <code>Shape</code> constructors.</p>
<h2>Stream API</h2>
<p>The <code>generate</code> and <code>iterate</code> methods in the Stream API receive a Supplier as parameter:</p>
<pre><code class="language-java">Supplier&lt;Double&gt; randomSupplier = () -&gt; Math.random();
Stream.generate(randomSupplier)
    .limit(10)
    .forEach(System.out::println);
</code></pre>
<p>It can be simplified using method references:</p>
<pre><code class="language-java">Stream.generate(Math::random)
    .limit(10)
    .forEach(System.out::println);
</code></pre>
<h2>Lazy initialization</h2>
<p>It is a design pattern where the creation of an object or computation of a value is deferred until it is needed. This technique improves performance and reduces memory usage, because it avoids unnecessary computations.</p>
<pre><code class="language-java">// Eager initialization
String eagerValue = "Eager Initialization";

// Lazy initialization using Supplier
Supplier&lt;String&gt; lazyValueSupplier = () -&gt; "Lazy Initialization";

// Value is not created until get() is called
System.out.println("Before accessing lazy value");
System.out.println(lazyValueSupplier.get()); // Output: Lazy Initialization
</code></pre>
<p>The example is useless, but let's imagine a heavy computation task instead of a single String. For this case, it is useful to ensure the object is created only once (memoization).</p>
<p>Let's create a custom wrapper class for this:</p>
<pre><code class="language-java">public class Lazy&lt;T&gt; {
    private final Supplier&lt;T&gt; supplier;
    private T value;

    public Lazy(Supplier&lt;T&gt; supplier) {
        this.supplier = supplier;
    }

    public T get() {
        if (value == null) {
            value = supplier.get();
        }
        return value;
    }
}
</code></pre>
<p>It is called like that:</p>
<pre><code class="language-java">Lazy&lt;String&gt; lazyValue = new Lazy&lt;&gt;(() -&gt; "Computed Value");

System.out.println("Before accessing lazy value");
System.out.println(lazyValue.get()); // Output: Computed Value
</code></pre>
<p>The syntax for creating a Lazy object in Java is verbose, since it's not a built-in class. In other JVM languages a variable can be declared <code>lazy</code>. For example, in Scala:</p>
<pre><code class="language-scala">lazy val lazyValue = "Computed Value"
</code></pre>
<h2>Generating an infinite list</h2>
<p>This is an application of lazy evaluation. It's a quite common case.</p>
<pre><code class="language-java"> // Generate an infinite stream of random numbers
Stream&lt;Double&gt; infiniteStream = Stream.generate(Math::random);
// Take the first 5 elements and print them
infiniteStream.limit(5).forEach(System.out::println);
</code></pre>
<pre><code class="language-java">// Generate an infinite stream of integers starting from 1
Stream&lt;Integer&gt; infiniteStream = Stream.iterate(1, n -&gt; n + 1);
// Take the first 5 elements and print them
infiniteStream.limit(5).forEach(System.out::println);
</code></pre>
<p>Scala's native support for laziness makes it more idiomatic for such tasks:</p>
<pre><code class="language-scala">val infiniteList = LazyList.continually(scala.util.Random.nextDouble())
// Take the first 5 elements and print them
println(infiniteList.take(5).toList)
</code></pre>
<h2>Lazy Evaluation in Kotlin</h2>
<pre><code class="language-kotlin">// Generate an infinite sequence of integers starting from 1
val infiniteSequence = generateSequence(1) { it + 1 }
// Take the first 5 elements and print them
println(infiniteSequence.take(5).toList())
</code></pre>
<p>In general, the <code>sequence</code> function is a builder needed for creating sequences lazily.</p>
<pre><code class="language-kotlin">val randomNumbers = sequence {
    while (true) {
        yield(Random.nextDouble())
    }
}

// Take the first 5 random numbers and print them
println(randomNumbers.take(5).toList())
</code></pre>
<p>Custom extension functions can be defined to create infinite sequences for specific use cases. This allows Kotlin to mimic the functional Scala syntax:</p>
<pre><code class="language-kotlin">fun Int.toInfiniteSequence(): Sequence&lt;Int&gt; = generateSequence(this) { it + 1 }

fun main() {
    // Create an infinite sequence starting from 10
    val infiniteSequence = 10.toInfiniteSequence()

    // Take the first 5 elements and print them
    println(infiniteSequence.take(5).toList()) 
}
</code></pre>
<h2>Summary</h2>
<p><strong>Suppliers</strong> are an important part of functional programming in Java.</p>
<p>They have two main use cases:</p>
<ul>
<li><p>To encapsulate the logic of value generation.</p>
</li>
<li><p>To allow separating the definition of how a value is generated from when that value is needed. This technique is called <strong>lazy evaluation</strong> and it's more easily implemented in Scala and Kotlin.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Lambda expressions and function types]]></title><description><![CDATA[Introduction to Lambda Expressions
A lambda expression or anonymous method is a shortcut to define an implementation of a functional interface.
It has the following syntax:
(parameters) -> {statements]]></description><link>https://blog.programwithjr.com/lambda-expressions-and-function-types</link><guid isPermaLink="true">https://blog.programwithjr.com/lambda-expressions-and-function-types</guid><category><![CDATA[Java]]></category><category><![CDATA[Lambda Expression]]></category><category><![CDATA[interface]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Thu, 16 Jan 2025 17:12:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/32df9af6-38de-45a5-89f3-2e34e96fcbd3.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Introduction to Lambda Expressions</h1>
<p>A lambda expression or anonymous method is a shortcut to define an implementation of a functional interface.</p>
<p>It has the following syntax:</p>
<pre><code class="language-java">(parameters) -&gt; {statements/s}
</code></pre>
<pre><code class="language-java">(Integer number) -&gt; {
    return number * 2;
}
</code></pre>
<p>The parameter type can be inferred:</p>
<pre><code class="language-java">(number) -&gt; {
    return number * 2;
}
</code></pre>
<p>Since the method body is a single expression, the curly braces and the return keyword are not necessary.</p>
<pre><code class="language-java">(number) -&gt; number * 2;
</code></pre>
<p>If there is only one parameter, the parentheses can be omitted:</p>
<pre><code class="language-java">number -&gt; number * 2;
</code></pre>
<p>Now we have a very -maybe too much- compact lambda expression. But how do we use it ?</p>
<pre><code class="language-java">function duplicate(int number) -&gt; number * 2;  // Invalid code
</code></pre>
<p>and then we might want to invocate the function:</p>
<pre><code class="language-java">duplicate(3); // Invalid code
</code></pre>
<p>But this does not work, <code>function</code> is not a Java keyword. There are only classes and interfaces in Java. In order to maintain its famous backward compatibility, the language designers decided to relate lambdas with ordinary interfaces:</p>
<pre><code class="language-java">@FunctionalInterface
public interface MyFunction {
    int duplicate(int number);
}
</code></pre>
<p>We can finally write a valid lambda expression:</p>
<pre><code class="language-java">public class MyClass implements MyFunction { 
    MyFunction myFunction = (number) -&gt; number * 2;
    ...........................................
}
</code></pre>
<p>and call it:</p>
<pre><code class="language-java">System.out.println(myFunction.duplicate(3)); // 6
</code></pre>
<p>We can now understand the definition given in the beginning of this article:</p>
<p><code>A lambda expression or anonymous method is an implementation of a functional interface. It was introduced in Java 8.</code></p>
<p>A functional interface is an interface that contains only one abstract method. Also called SAM ("single abstract method") interface.</p>
<p>The <code>@FunctionalInterface</code> annotation is used to mark interfaces that only have one abstract method. It is not required, since there might be SAM interfaces declared in earlier Java versions.</p>
<pre><code class="language-java">@FunctionalInterface   // This annotation is optional, but recommended
public interface MyFunction {
    int duplicate(int number);
}
</code></pre>
<p>In other words, the implementation of the abstract method of a functional interface is the equivalent to a function in other languages. In a modern JVM language like Kotlin, this is the equivalent code:</p>
<pre><code class="language-kotlin">fun duplicate(number: Int): Int {
    return number * 2
}
</code></pre>
<h1>Function Types</h1>
<p>Do we have to write a functional interface every time we want to use a lambda expression ? No, because Java provides a series of pre-defined functional interfaces called <code>function types</code>.</p>
<h2>Function&lt;T, R&gt; and friends</h2>
<p>These functional interfaces represent functions that take a parameter of type <code>T</code> and return a result of type <code>R</code>.</p>
<pre><code class="language-java">Function&lt;Integer, Integer&gt; duplicate = x -&gt; x * 2;
System.out.println(duplicate.apply(3));     // 6
</code></pre>
<p>Notice the parameters are not primitive types, but objects.</p>
<p>Equivalent code in Kotlin:</p>
<pre><code class="language-kotlin">fun duplicate(x: Int): Int {
    return x * 2
}
</code></pre>
<p>It is probably more clear in Kotlin or Scala, but you can get used to it. In my opinion, Java language designers did a good work to maintain the backwards compatibility. However, using these pre-defined function types makes you to have to learn a number of other functional interfaces and their corresponding default methods.</p>
<p>Default methods are provided for the Function interface: <code>andThen()</code> and <code>compose()</code></p>
<pre><code class="language-java">Function&lt;Integer, Integer&gt; duplicate = x -&gt; x * 2;
Function&lt;Integer, Integer&gt; addOne = x -&gt; x + 1;
Function&lt;Integer, Integer&gt; duplicatePlusOne = duplicate.andThen(addOne);
System.out.println(duplicatePlusOne.apply(3));     // 7
</code></pre>
<p>That code is equivalent to this one:</p>
<pre><code class="language-java">Function&lt;Integer, Integer&gt; duplicate = x -&gt; x * 2;
Function&lt;Integer, Integer&gt; addOne = x -&gt; x + 1;
Function&lt;Integer, Integer&gt; duplicatePlusOne = addOne.compose(duplicate);
System.out.println(duplicatePlusOne.apply(3));     // 7
</code></pre>
<h2>BiFunction&lt;T, U, R&gt; and friends</h2>
<p>These functional interfaces represent functions that take two parameters of type <code>T</code> and <code>U</code> and return a result of type <code>R</code>.</p>
<pre><code class="language-java">BiFunction&lt;Integer, Integer, Integer&gt; add = (x, y) -&gt; x + y;
System.out.println(add.apply(3, 4));     // 7
</code></pre>
<h2>Other pre-defined function types</h2>
<pre><code class="language-java">UnaryOperator&lt;Integer&gt; square = (x) -&gt; x * x;
System.out.println(square.apply(3));     // 9
</code></pre>
<pre><code class="language-java">BinaryOperator&lt;Integer&gt; add = (x, y) -&gt; x + y;
System.out.println(add.apply(3, 4));     // 7
</code></pre>
<p>and when a primitive data type is returned:</p>
<ul>
<li><p>ToIntFunction - takes a T and returns an int.</p>
</li>
<li><p>ToLongFunction - takes a T and returns a long.</p>
</li>
<li><p>ToDoubleFunction - takes a T and returns a double.</p>
</li>
</ul>
<p>The <code>Function</code> interface is for operations that take a single parameter and return a single value, while the <code>BiFunction</code> interface is designed for operations that take two parameters.</p>
<h2>Predicate&lt;T&gt;</h2>
<p>This functional interface represents functions that take a parameter of type <code>T</code> and return a boolean value. It's mainly used for filtering and evaluating conditions.</p>
<pre><code class="language-java">Predicate&lt;Integer&gt; isEven = x -&gt; x % 2 == 0;
boolean result = isEven.test(4); // true
</code></pre>
<p>The Predicate interface also provides several default methods: <code>and()</code>, <code>or()</code>, <code>negate()</code>:</p>
<pre><code class="language-java">Predicate&lt;Integer&gt; isEven = x -&gt; x % 2 == 0;
Predicate&lt;Integer&gt; isGreaterThan10 = x -&gt; x &gt; 10;
Predicate&lt;Integer&gt; isEvenAndGreaterThan10 = isEven.and(isGreaterThan10);
boolean result = isEvenAndGreaterThan10.test(12); // true
</code></pre>
<pre><code class="language-java">Predicate&lt;String&gt; containsA = str -&gt; str.contains("A");
Predicate&lt;String&gt; containsB = str -&gt; str.contains("B");
Predicate&lt;String&gt; containsEither = containsA.or(containsB);
</code></pre>
<pre><code class="language-java">Predicate&lt;Integer&gt; isEven = x -&gt; x % 2 == 0;
Predicate&lt;Integer&gt; isOdd = isEven.negate();
</code></pre>
<h2>Consumer&lt;T&gt;</h2>
<p>It's a functional interface that takes a parameter of type <code>T</code> and performs an action without returning a value.</p>
<pre><code class="language-java">Consumer&lt;String&gt; greeting = s -&gt; System.out.println(s);
greeting.accept("Hello, World!");
</code></pre>
<p>In my opinion, the above default method could have been called <code>apply()</code> in order to be consistent with the Function function type.</p>
<p>The Consumer interface also provides the default method <code>andThen()</code>, which allows for chaining multiple Consumer operations. This is similar to the <code>and()</code> method of the Function interface seen above.</p>
<h2>Supplier&lt;T&gt;</h2>
<p>It's a functional interface that returns a value of type <code>T</code> without taking any input arguments. It's the oppossite of the Consumer. It has a single abstract method called <code>T get()</code>.</p>
<pre><code class="language-java">Supplier&lt;String&gt; supplier = () -&gt; "Hello, World!";
System.out.println(supplier.get());
</code></pre>
<p>Suppliers are useful to generate values in a lazy way. The exact meaning of this deserves its own article.</p>
<h1>Method References</h1>
<p>Besides lambdas, Java 8 introduced method references, which are a way to refer to a method without having to specify the full method signature.</p>
<pre><code class="language-java">Consumer&lt;String&gt; greeting = s -&gt; System.out.println(s);
Consumer&lt;String&gt; greeting = System.out::println;
greeting.accept("Hello, World!");
</code></pre>
<p>The general syntax for method references is <code>ClassName::methodName</code>, where <code>ClassName</code> is the name of the class containing the method and <code>methodName</code> is the name of the method to be called.</p>
<p>This is especially useful when using custom classes:</p>
<pre><code class="language-java">class Employee {
    String getName() {
        return name;
    }
    ......................
}
</code></pre>
<p>With method references we can do this:</p>
<pre><code class="language-java">Consumer&lt;Employee&gt; printName = employee -&gt; employee.getName();
Consumer&lt;Employee&gt; printName = Employee::getName;
</code></pre>
<h2>Constructor References</h2>
<p>Instead of</p>
<pre><code class="language-java">Supplier&lt;Employee&gt; employee = () -&gt; new Employee();
</code></pre>
<p>use</p>
<pre><code class="language-java">Supplier&lt;Employee&gt; employee = Employee::new;
</code></pre>
<h1>Lambda expressions and Streams</h1>
<p>In conjunction with lambdas, Streams provide a way to process sequences of data elements in a functional style. Streams allow to perform operations like filtering, mapping, and reducing on data, making the code much more concise and readable.</p>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sumOfEvenSquares = numbers.stream()
    .filter(number -&gt; number % 2 == 0)
    .map(number -&gt; number * number)
    .reduce(0, Integer::sum);

System.out.println("Sum of squares of even numbers:" + sumOfEvenSquares);
</code></pre>
<p>There is much more to explain about the Streams API, but this is enough to show how they use lambda expressions.</p>
<h1>Lambda Expressions in other Java packages</h1>
<p>In addition to the function types, there are more pre-defined functional interfaces in other Java libraries.</p>
<pre><code class="language-java">@FunctionalInterface
public interface Comparator&lt;T&gt; {
    int compare(T obj1, T obj2);
}
</code></pre>
<p>The abstract method above compares its two arguments for order. Returns a negative integer, zero, or a positive integer if the first argument is less than, equal to, or greater than the second. (Source: <a href="https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/util/Comparator.html">Comparator official docs</a>)</p>
<p>When using custom classes, we probably have to create our own Comparator:</p>
<pre><code class="language-java">public class EmployeeComparator implements Comparator&lt;Employee&gt; {
    @Override
    public int compare(Employee empl1, Employee empl2) {
        return Integer.compare(empl1.getAge(), empl2.getAge()); 
    }
}
</code></pre>
<p>The Comparator interface has a number of default and static methods that can be used with lambda expressions.</p>
<h1>Functional Interfaces before Java 8</h1>
<p>Although the term <code>functional interface</code> was introduced in Java 8, there were a number of interfaces with a single abstract method in earlier Java versions.</p>
<p>For example, the <code>Comparator</code> interface was declared in the same way, but without using the <code>@FunctionalInterface</code> annotation.</p>
<p>The main difference is that the <code>Comparator</code> interface was implemented using anonymous inner classes:</p>
<pre><code class="language-java">Collections.sort(employeeList, new Comparator&lt;Employee&gt;() {
    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getName().compareTo(e2.getName());
    }
});
</code></pre>
<p>This was more verbose than the lambda expressions.</p>
<h1>Conclusion</h1>
<p>We have explained lambda expressions and functional interfaces, features introduced in Java 8. Then we explained the different function types, which allow us to create powerful transformations of data. Method references provide a shorthand for lambda expressions, making our code even more readable.</p>
<p>A small comparison with the equivalent code used with anonymous classes allows us to observe how powerful the lambda expressions are when used with pre-defined functional interfaces.</p>
]]></content:encoded></item><item><title><![CDATA[Optionals in Java]]></title><description><![CDATA[Introduction
Optional is a class introduced in Java 8 to handle null values in order to avoid the dreadful NullPointerException (NPE). 
It is a wrapper class that can be used to represent a value that]]></description><link>https://blog.programwithjr.com/optionals-in-java</link><guid isPermaLink="true">https://blog.programwithjr.com/optionals-in-java</guid><category><![CDATA[Java]]></category><category><![CDATA[Optional]]></category><category><![CDATA[Optional chaining]]></category><category><![CDATA[jvm]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Scala]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Sun, 05 Jan 2025 23:42:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/644efa8f367f154db863c1b0/a54df25f-40ac-4dd8-9010-123ba367c571.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>Optional is a class introduced in Java 8 to handle null values in order to avoid the dreadful NullPointerException (NPE). 
It is a wrapper class that can be used to represent a value that may be null or not.</p>
<p>Before Java 8, developers had to use null checks to handle null values.</p>
<p>Let's say we have a method that returns an employee from a database.</p>
<pre><code class="language-java">public static void main(String[] args) {
    var employee = getEmployee("John");
}
</code></pre>
<pre><code class="language-java">public Employee getEmployee(String name) {
    Employee employee = getEmployeeByName(name);

    if (employee != null) {
        return employee;
    } else {
        return throw new IllegalArgumentException("Employee not found");
    }
}
</code></pre>
<p>This is the equivalent code with Optional.</p>
<pre><code class="language-java">public static void main(String[] args) {
    var employee = getEmployee("John");
}
</code></pre>
<pre><code class="language-java">public Optional&lt;Employee&gt; getEmployee(String name) {
    Optional&lt;Employee&gt; employee = getEmployeeByName(name);

    if (employee.isPresent()) {
        return employee.get();
    } else {
        return employee.orElseThrow(() -&gt; new IllegalArgumentException("Employee not found"));
        // return Optional.of(new Employee());    // or return a default employee
        // return Optional.empty();               // or return an empty optional
    }
}
</code></pre>
<p>But, wait! what is the point of the Optional class if we can achieve the same result using a null check?</p>
<p>There is a subtle difference: when a method returns an Optional, that method is indicating that it may or may not return a value. So you have to be prepared to handle both cases.
But that is not a big improvement over the null check.</p>
<h2>Real improvements with Optional</h2>
<p>The Optional API provides additional methods.</p>
<pre><code class="language-java">public static void main(String[] args) {
    var employee = getEmployeee("John");
}
</code></pre>
<p>The <code>orElse()</code> method returns the wrapped value or the provided value as if the optional is empty. It's preferred over the <code>get()</code> and <code>isPresent()</code> methods.</p>
<pre><code class="language-java">public Optional&lt;Employee&gt; getEmployeee(String name) {
    return getEmployeeByName(name)
               .orElse(new Employee());
}
</code></pre>
<h2>Chaining stream operations</h2>
<p>Let's try to retrieve an employee age from the database using null checks.</p>
<pre><code class="language-java">public int getEmployeeAge(String name) {
    Employee employee = getEmployeeByName(name);

    if (employee != null) {
        if (employee.getAge() != null) {
            return employee.getAge();
        } else {
            return throw new IllegalArgumentException("Employee age is null");
        }
    }
}
</code></pre>
<p>It's a bit ugly and cumbersome. More important, forgetting one null check can cause a NPE.
The code above can be simplified by chaining stream operations. </p>
<p>The Optional API provides a much more robust code.</p>
<pre><code class="language-java">public Optional&lt;Integer&gt; getEmployeeAge(String name) {
    Optional&lt;Employee&gt; optionalEmployee = getEmployeeByName(name);
    return getEmployeeByName(name)
               .map(Employee::getAge)
               .orElse(0);
}
</code></pre>
<p>We might want to throw an exception if the age is null.</p>
<pre><code class="language-java">public Optional&lt;Integer&gt; getEmployeeAge(String name) {
    return getEmployeeByName(name)
               .map(Employee::getAge)
               .orElseThrow(() -&gt; new IllegalArgumentException("Employee age is null"));
}
</code></pre>
<h2>Do not overuse Optional</h2>
<p>Optional can also be used for method parameters, but it does not make any sense. It shoul be used only for method return values.</p>
<pre><code class="language-java">// Strange use of Optional
public Optional&lt;Integer&gt; getEmployeeAge(Optional&lt;String&gt; name) {
    ..................
}
</code></pre>
<h2>Bonus: how other languages handle null values</h2>
<h3>Scala</h3>
<p>Scala, one important JVM language, uses the <code>Option</code> class, which is a wrapper class.</p>
<pre><code class="language-scala">def getEmployeeAge(name: String): Option[Int] = {
  val employee = getEmployeeByName(name)
  employee.map(_.age)
}
</code></pre>
<h3>Kotlin</h3>
<p>Other languages use an operator instead of a wrapper object to handle null values.
In Kotlin the <code>?</code> is called the <strong>safe call operator</strong>. </p>
<pre><code class="language-kotlin">// In Kotlin the returned data type is put after the semicolon
fun getEmployeeAge(String name): Int? {
    val employee = getEmployeeByName(name)
    return employee?.age // similar to `orElse(null)` in Java
}
</code></pre>
<p>If you want to provide a default value, you can use the <code>?:</code> operator.</p>
<pre><code class="language-kotlin">val age = getEmployeeAge("John") ?: 0  // similar to `orElse(0)` in Java
</code></pre>
<p>Outside the JVM world, C# also uses the <code>?</code>  or <strong>null-conditional operator</strong> to indicate that a variable may be null.</p>
<h3><code>C#</code></h3>
<pre><code class="language-csharp">public int? GetEmployeeAge(string name) {
    var employee = GetEmployeeByName(name);
    return employee?.Age;
}
</code></pre>
<h2>Conclusion</h2>
<p>As we saw, Optional is not just a replacement for null checks. It is a wrapper class that can be used to represent a value that may be null or not. We can appreciate its real power when we chain stream operations.
The Optional methods <strong>get()</strong> and <strong>isPresent()</strong> are discouraged to use. So much that the language designers regret having creating them.</p>
<p>Other languages like <strong>Kotlin</strong> and <strong>C#</strong> use the <code>?</code> operator to handle null values. <strong>Scala</strong> provides a similar solution.</p>
]]></content:encoded></item><item><title><![CDATA[Java Dependency Conflicts: Solutions and Tips]]></title><description><![CDATA[Introduction
In npm's Node JS, the same dependency or library may have different versions depending on the various parts of an application.
But Java and its build tools are not designed to support using two different versions of the same library at r...]]></description><link>https://blog.programwithjr.com/java-dependency-conflicts-solutions-and-tips</link><guid isPermaLink="true">https://blog.programwithjr.com/java-dependency-conflicts-solutions-and-tips</guid><category><![CDATA[Java]]></category><category><![CDATA[maven]]></category><category><![CDATA[gradle]]></category><category><![CDATA[dependency management]]></category><dc:creator><![CDATA[José Ramón (JR)]]></dc:creator><pubDate>Wed, 28 Aug 2024 15:29:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/6EH_ILd3S50/upload/85aef58b511cc4f3a3d7cae509e96444.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In npm's Node JS, the same dependency or library may have different versions depending on the various parts of an application.</p>
<p>But Java and its build tools are not designed to support using two different versions of the same library at runtime. If you want multiple versions at the same time, at runtime, then you need to do classloader tricks.</p>
<h2 id="heading-what-are-dependency-conflicts">What are dependency conflicts</h2>
<p>Also called dependency hell, these terms refer to the conflict caused by using different versions of the same library, as shown above.</p>
<pre><code class="lang-java">&lt;!-- Project dependencies --&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.example&lt;/groupId&gt;
            &lt;artifactId&gt;study-maven-<span class="hljs-number">2</span>&lt;/artifactId&gt;
            &lt;version&gt;<span class="hljs-number">1.0</span>-SNAPSHOT&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.example&lt;/groupId&gt;
            &lt;artifactId&gt;study-maven-<span class="hljs-number">3</span>&lt;/artifactId&gt;
            &lt;version&gt;<span class="hljs-number">1.0</span>-SNAPSHOT&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

&lt;groupId&gt;org.example&lt;/groupId&gt;
    &lt;artifactId&gt;study-maven-<span class="hljs-number">2</span>&lt;/artifactId&gt;
    &lt;version&gt;<span class="hljs-number">1.0</span>-SNAPSHOT&lt;/version&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.google.guava&lt;/groupId&gt;
            &lt;artifactId&gt;guava&lt;/artifactId&gt;
            &lt;version&gt;<span class="hljs-number">30.1</span>.<span class="hljs-number">1</span>-jre&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

&lt;groupId&gt;org.example&lt;/groupId&gt;
    &lt;artifactId&gt;study-maven-<span class="hljs-number">3</span>&lt;/artifactId&gt;
    &lt;version&gt;<span class="hljs-number">1.0</span>-SNAPSHOT&lt;/version&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.google.guava&lt;/groupId&gt;
            &lt;artifactId&gt;guava&lt;/artifactId&gt;
            &lt;version&gt;<span class="hljs-number">29.0</span>-jre&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<p>In this example, only one version of Guava will be imported, but which one ?</p>
<p>Before answering this question, we need to explain briefly another concept.</p>
<h3 id="heading-the-dependency-graph">The dependency graph</h3>
<p>A <strong>dependency</strong> <strong>graph</strong> <strong>is a graph</strong> that represents dependencies and the relations among them.</p>
<p>The two most used build tools -Maven and Gradle- have a very helpful tool to present all dependencies and their versions:</p>
<pre><code class="lang-java">mvn dependency:tree -Dverbose
</code></pre>
<pre><code class="lang-java">gradle dependencies
</code></pre>
<h2 id="heading-resolution-strategy">Resolution strategy</h2>
<p>The strategy used to select which library version is chosen in runtime is different in Apache Maven and in Gradle.</p>
<h3 id="heading-apache-maven">Apache Maven</h3>
<p><strong>Maven uses a nearest first strategy</strong>.</p>
<p>It will take the shortest path to a dependency and use that version. In case there are multiple paths of the same length, the first one wins.</p>
<p>The main drawback of this method is that it is ordering dependent. Keeping order in a very large graph can be a challenge. For example, what if the new version of a dependency ends up having its own dependency declarations in a different order than the previous version? This could have unwanted impact on resolved versions.</p>
<h3 id="heading-gradle">Gradle</h3>
<p>By default, <strong>Gradle will select the highest version</strong> for a dependency when there's a conflict.</p>
<p>You can force a particular version to be used with a custom resolutionStrategy. More info in the <a target="_blank" href="http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html">Gradle docs</a></p>
<pre><code class="lang-java">configurations.all {
 resolutionStrategy { force <span class="hljs-string">'com.google.guava:guava:15.0'</span> } 
}
</code></pre>
<p>This does not add a dependency on guava 15.0, but forces the use of 15.0 if there is a dependency (even transitively).</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This was a very short article that introduced some basic concepts in Java dependency management.</p>
<p>We will explain some solutions in the next part of these series.</p>
<h2 id="heading-references-and-further-reading">References and Further Reading</h2>
<ul>
<li><p><a target="_blank" href="https://www.baeldung.com/maven-dependency-graph">https://www.baeldung.com/maven-dependency-graph</a></p>
</li>
<li><p><a target="_blank" href="https://liam8.github.io/2021/09/24/How-to-solve-dependency-conflicts-with-Maven/">https://liam8.github.io/2021/09/24/How-to-solve-dependency-conflicts-with-Maven/</a></p>
</li>
<li><p><a target="_blank" href="https://docs.gradle.org/current/userguide/dependency_resolution.html">https://docs.gradle.org/current/userguide/dependency_resolution.html</a></p>
</li>
<li><p><a target="_blank" href="https://www.baeldung.com/maven-version-collision">https://www.baeldung.com/maven-version-collision</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>