<?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[The Java Knowledge Ocean: Java: Usage & Interview Tips]]></title><description><![CDATA[This column introduces common Java interview contents and related usage skills.]]></description><link>https://seabreeze0828.substack.com/s/java-knowledge-usage-and-interview</link><image><url>https://substackcdn.com/image/fetch/$s_!MgS-!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2006b880-951e-4af1-8243-52e5cdef4c73_676x676.png</url><title>The Java Knowledge Ocean: Java: Usage &amp; Interview Tips</title><link>https://seabreeze0828.substack.com/s/java-knowledge-usage-and-interview</link></image><generator>Substack</generator><lastBuildDate>Thu, 20 Aug 2026 12:53:56 GMT</lastBuildDate><atom:link href="https://seabreeze0828.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Dylan Smith]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[dylan0828@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[dylan0828@substack.com]]></itunes:email><itunes:name><![CDATA[Dylan Smith]]></itunes:name></itunes:owner><itunes:author><![CDATA[Dylan Smith]]></itunes:author><googleplay:owner><![CDATA[dylan0828@substack.com]]></googleplay:owner><googleplay:email><![CDATA[dylan0828@substack.com]]></googleplay:email><googleplay:author><![CDATA[Dylan Smith]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[JDK 8 → 17 → 21 → 25: The Key Leaps Across Four LTS Generations, Explained at Once]]></title><description><![CDATA[The article combines extensive code and charts for explanation.]]></description><link>https://seabreeze0828.substack.com/p/jdk-8-17-21-25-the-key-leaps-across</link><guid isPermaLink="false">https://seabreeze0828.substack.com/p/jdk-8-17-21-25-the-key-leaps-across</guid><dc:creator><![CDATA[Dylan Smith]]></dc:creator><pubDate>Mon, 10 Aug 2026 12:15:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!sHV9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Preface</strong></h2><p>This article is a technical summary from my own experience upgrading from JDK 8 all the way to JDK 25 in production. It covers four LTS releases &#8212; JDK 8 (2014), JDK 17 (2021), JDK 21 (2023), and JDK 25 (2025) &#8212; spanning 11 years of Java evolution.</p><p>I&#8217;m not going to dump a feature list and call it a day. For each version I&#8217;ll include real code examples, analysis of JVM internals, and GC tuning parameters. If you&#8217;re considering a version upgrade, or you want to understand what actually changed at a fundamental level over this decade of the Java platform, this article should help.</p><h2><strong>1. Version Positioning and Release Strategy</strong></h2><p>First, let&#8217;s make the positioning of the four versions clear:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0fb2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0fb2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 424w, https://substackcdn.com/image/fetch/$s_!0fb2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 848w, https://substackcdn.com/image/fetch/$s_!0fb2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 1272w, https://substackcdn.com/image/fetch/$s_!0fb2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0fb2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png" width="1313" height="184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:184,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0fb2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 424w, https://substackcdn.com/image/fetch/$s_!0fb2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 848w, https://substackcdn.com/image/fetch/$s_!0fb2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 1272w, https://substackcdn.com/image/fetch/$s_!0fb2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a1ad26-cfc2-4485-bda3-19bdaddcdf1c_1313x184.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sHV9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sHV9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 424w, https://substackcdn.com/image/fetch/$s_!sHV9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 848w, https://substackcdn.com/image/fetch/$s_!sHV9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!sHV9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sHV9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg" width="1313" height="342" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:342,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!sHV9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 424w, https://substackcdn.com/image/fetch/$s_!sHV9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 848w, https://substackcdn.com/image/fetch/$s_!sHV9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!sHV9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd1d1a27-39d9-4da7-9571-91b10e609541_1313x342.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The change in release cadence is the key to understanding the Java ecosystem:</p><ul><li><p>Before JDK 8: major versions were 2&#8211;3 years apart, features piled up, and delays were the norm (JDK 9 slipped by three years)</p></li><li><p>After JDK 9: switched to the six-month train model, with releases every March and September</p></li><li><p>LTS cadence: originally one LTS every three years (8 &#8594; 11 &#8594; 17); starting with JDK 17 it became every two years (17 &#8594; 21 &#8594; 25)</p></li></ul><p>This strategy shift directly affected our technology choices. Many teams stayed on JDK 8 for nearly a decade, mainly because there was no LTS worth the risk of upgrading between JDK 9 and JDK 16. JDK 17 was the first version that really made everyone think &#8220;it&#8217;s time to upgrade.&#8221;</p><p>A word on licensing: after JDK 8u211, commercial use of Oracle JDK requires a paid license. Starting with JDK 17, Oracle restored the NFTC (No-Fee Terms and Conditions) license, which allows free commercial use. That said, many companies have already moved to distributions like Adoptium (Eclipse Temurin), Amazon Corretto, and Azul Zulu, which are free at every version.</p><h2><strong>2. Language Feature Evolution</strong></h2><h3><strong>2.1 JDK 8: The Lambda &amp; Stream Functional Revolution</strong></h3><p>JDK 8 was the most significant language-level change in Java&#8217;s history. It introduced four core features at once &#8212; Lambda, Stream, Optional, and the new date-time API &#8212; and directly changed Java&#8217;s programming paradigm.</p><p><strong>Lambda expressions and functional interfaces</strong></p><p>Before JDK 8, writing a sort looked like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;502353fb-4b9c-42bd-bd1d-88ac671c7e05&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 7 style
List&lt;String&gt; names = Arrays.asList(&#8221;Charlie&#8221;, &#8220;Alice&#8221;, &#8220;Bob&#8221;);
Collections.sort(names, new Comparator&lt;String&gt;() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});</code></pre></div><p>After JDK 8:</p><pre><code><span>// JDK 8 style
List&lt;String&gt; names = Arrays.asList(&#8221;Charlie&#8221;, &#8220;Alice&#8221;, &#8220;Bob&#8221;);
names.sort(String::compareTo);</span></code></pre><p>The underlying implementation of Lambda is worth understanding: it is not syntactic sugar for anonymous inner classes. The compiler uses the <code>invokedynamic</code> instruction and generates the implementation class at runtime through <code>LambdaMetafactory</code>, avoiding the problem of anonymous inner classes generating a large number of <code>.class</code> files at compile time. You can see the difference with <code>javap -c -p</code>:</p><pre><code><span>// Anonymous inner class: generates MyClass$1.class
// Lambda: compiles to an invokedynamic instruction
0: invokedynamic #2, 0  // InvokeDynamic #0:compare:()Ljava/util/Comparator;</span></code></pre><p><strong>Stream API</strong></p><p>The core design of Stream is lazy evaluation. Intermediate operations (filter, map, flatMap) don&#8217;t execute immediately; only a terminal operation (collect, forEach, reduce) triggers the entire pipeline to be processed in one pass:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;bb52c84e-c8ba-4d8c-858d-72586e1661b7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Real-world scenario: extract emails of high-value customers from an order list
List&lt;String&gt; vipEmails = orders.stream()
    .filter(o -&gt; o.getAmount().compareTo(new BigDecimal(&#8221;10000&#8221;)) &gt; 0)
    .map(Order::getCustomer)
    .filter(c -&gt; c.getVipLevel() &gt;= 3)
    .map(Customer::getEmail)
    .distinct()
    .sorted()
    .collect(Collectors.toList());</code></pre></div><p>My advice on parallel streams: use them very rarely in web applications. Under the hood, parallel streams use <code>ForkJoinPool.commonPool()</code>, a globally shared thread pool. If you process a long-running operation with a parallel stream inside one HTTP request, it affects the parallel streams running in other requests. We once hit production timeouts because of exactly this.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4AhC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4AhC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 424w, https://substackcdn.com/image/fetch/$s_!4AhC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 848w, https://substackcdn.com/image/fetch/$s_!4AhC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 1272w, https://substackcdn.com/image/fetch/$s_!4AhC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4AhC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png" width="1313" height="487" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:487,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!4AhC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 424w, https://substackcdn.com/image/fetch/$s_!4AhC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 848w, https://substackcdn.com/image/fetch/$s_!4AhC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 1272w, https://substackcdn.com/image/fetch/$s_!4AhC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eb841d3-b9db-4be3-a9ef-88e378ee5651_1313x487.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above shows the complete Stream pipeline &#8212; from the data source to the intermediate operations (lazy) to the terminal operation (triggering execution) &#8212; along with the Fork-Join divide-and-conquer model of parallel streams.</p><p><strong>Optional</strong></p><pre><code><span>// Chain handling of values that may be null
String cityName = Optional.ofNullable(user)
    .map(User::getAddress)
    .map(Address::getCity)
    .map(City::getName)
    .orElse(&#8221;Unknown&#8221;);</span></code></pre><p><strong>The java.time API</strong></p><p>It finally replaced the disastrous <code>java.util.Date</code> and <code>Calendar</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;5841819d-ffaf-4dbf-a8a6-1dfdfa24d475&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 8 date handling
LocalDateTime now = LocalDateTime.now();
LocalDateTime meetingTime = now.plusHours(2).withMinute(0).withSecond(0);
Duration duration = Duration.between(now, meetingTime);
System.out.println(&#8221;Minutes until the meeting: &#8220; + duration.toMinutes());

// Time zone handling
ZonedDateTime shanghaiTime = ZonedDateTime.now(ZoneId.of(&#8221;Asia/Shanghai&#8221;));
ZonedDateTime newYorkTime = shanghaiTime.withZoneSameInstant(ZoneId.of(&#8221;America/New_York&#8221;));</code></pre></div><h3><strong>2.2 The Key Transition Features of JDK 9&#8211;16</strong></h3><p>Many people skip this stretch, but in reality every transition feature from JDK 9&#8211;16 became standard in later LTS releases. If you don&#8217;t understand how they evolved, those features will feel like they &#8220;appeared out of nowhere&#8221; when you use JDK 17/21.</p><p><strong>JDK 9: The module system (Project Jigsaw)</strong></p><pre><code><span>// module-info.java
module com.myapp.core {
    requires java.sql;
    requires java.logging;
    exports com.myapp.core.api;
    opens com.myapp.core.model to com.fasterxml.jackson.databind;
}</span></code></pre><p>JDK 9 also introduced collection factory methods, JShell, and private interface methods:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;db8401d8-878f-4156-a491-d6475999f6f8&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Immutable collections (JDK 9)
List&lt;String&gt; list = List.of(&#8221;a&#8221;, &#8220;b&#8221;, &#8220;c&#8221;);
Map&lt;String, Integer&gt; map = Map.of(&#8221;key1&#8221;, 1, &#8220;key2&#8221;, 2);

// Private interface methods
public interface Validator {
    default boolean isValid(String input) {
        return !isEmpty(input) &amp;&amp; checkFormat(input);
    }
    private boolean isEmpty(String input) {
        return input == null || input.isBlank();
    }
    private boolean checkFormat(String input) {
        return input.matches(&#8221;[a-zA-Z]+&#8221;);
    }
}</code></pre></div><p><strong>JDK 10: Local variable type inference (var)</strong></p><pre><code><span>// var is not dynamic typing; it is compile-time type inference
var userList = new ArrayList&lt;User&gt;();        // inferred as ArrayList&lt;User&gt;
var stream = userList.stream();              // inferred as Stream&lt;User&gt;
var result = Map.of(&#8221;key&#8221;, List.of(1, 2));   // inferred as Map&lt;String, List&lt;Integer&gt;&gt;</span></code></pre><p><strong>JDK 11: String enhancements, HttpClient standardized</strong></p><pre><code><span>// New String methods
&#8220;  hello  &#8220;.strip();           // &#8220;hello&#8221; (Unicode-aware trim)
&#8220;hello&#8221;.repeat(3);             // &#8220;hellohellohello&#8221;
&#8220;line1\nline2\n&#8221;.lines()       // Stream&lt;String&gt;
    .forEach(System.out::println);
&#8220;&#8221;.isBlank();                  // true

// Single-file execution
// $ java HelloWorld.java    (no need to run javac first)</span></code></pre><p><strong>JDK 14: Records (preview), instanceof pattern matching (preview)</strong></p><pre><code><span>// Record: immutable data carrier
record Point(int x, int y) {}

// Helpful NPE messages (final in JDK 14)
// Before: NullPointerException
// After: Cannot invoke &#8220;String.length()&#8221; because &#8220;a.b.name&#8221; is null</span></code></pre><p><strong>JDK 15: Text Blocks</strong></p><pre><code><span>String json = &#8220;&#8221;&#8220;
        {
            &#8220;name&#8221;: &#8220;Zhang San&#8221;,
            &#8220;age&#8221;: 28,
            &#8220;roles&#8221;: [&#8221;admin&#8221;, &#8220;user&#8221;]
        }
        &#8220;&#8221;&#8220;;</span></code></pre><h3><strong>2.3 JDK 17: The Maturation of Language Features</strong></h3><p>JDK 17 finalized all the features previewed between JDK 14 and 16, forming a complete &#8220;modern Java&#8221; feature set.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wEpP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wEpP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wEpP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wEpP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wEpP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wEpP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg" width="1313" height="303" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:303,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!wEpP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wEpP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wEpP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wEpP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd2ab371-5aeb-4336-b334-85ae77f5dea1_1313x303.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Sealed Classes (JEP 409)</strong></p><p>Sealed classes restrict the set of permitted subclasses. Combined with pattern matching, the compiler can perform exhaustive checks:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YzTu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YzTu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YzTu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YzTu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YzTu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YzTu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg" width="1313" height="513" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:513,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!YzTu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YzTu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YzTu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YzTu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d006d1-5d90-4e35-96e4-0ed994c22d53_1313x513.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above shows the inheritance constraints of Sealed Classes &#8212; a sealed interface only allows the specified subclasses to implement it, final subclasses can no longer be inherited, and non-sealed subclasses remain open for extension.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;1a778d56-5356-4d02-b58e-8243dd405fc5&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Define a sealed shape hierarchy
public sealed interface Shape permits Circle, Rectangle, Triangle {
    double area();
}

public record Circle(double radius) implements Shape {
    public double area() { return Math.PI * radius * radius; }
}

public record Rectangle(double width, double height) implements Shape {
    public double area() { return width * height; }
}

public record Triangle(double base, double height) implements Shape {
    public double area() { return 0.5 * base * height; }
}</code></pre></div><p><strong>Pattern Matching for instanceof (JEP 394)</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;d17beba4-dcbd-4a8b-b0ed-b5283a749e1e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 16 and earlier style
if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.length());
}

// JDK 17 style
if (obj instanceof String s) {
    System.out.println(s.length());
}

// Combined with sealed classes
public static String describe(Shape shape) {
    if (shape instanceof Circle c) {
        return &#8220;Circle with radius &#8220; + c.radius();
    } else if (shape instanceof Rectangle r) {
        return &#8220;Rectangle &#8220; + r.width() + &#8220;x&#8221; + r.height();
    } else if (shape instanceof Triangle t) {
        return &#8220;Triangle with base &#8220; + t.base();
    }
    // Sealed classes guarantee this line is unreachable, but the compiler
    // does not perform exhaustiveness checks on if-else chains.
    // You need switch pattern matching (JDK 21) for compile-time exhaustiveness.
    throw new IllegalStateException();
}</code></pre></div><p>Other notable JDK 17 changes:</p><ul><li><p>Removed the Graal interfaces for AOT and JIT compilers (JEP 410) &#8212; this means if you want to use GraalVM, you need to install it separately</p></li><li><p>Strong encapsulation of JDK internal APIs (JEP 403) &#8212; <code>--illegal-access=permit</code> no longer takes effect</p></li><li><p>Removed RMI Activation (JEP 407)</p></li><li><p>Restored always-strict floating-point semantics (JEP 306)</p></li></ul><h3><strong>2.4 The JDK 18&#8211;20 Transition</strong></h3><p>These three non-LTS releases paved the way for the two killer features of JDK 21:</p><ul><li><p>JDK 18: default charset changed to UTF-8 (JEP 400), Simple Web Server (JEP 408)</p></li><li><p>JDK 19: Virtual Threads first preview (JEP 425), Structured Concurrency incubated (JEP 428)</p></li><li><p>JDK 20: Scoped Values incubated (JEP 429), Record Patterns second preview (JEP 432)</p></li></ul><h3><strong>2.5 JDK 21: The Concurrency Model Revolution</strong></h3><p>JDK 21 is the most significant change to the Java platform since JDK 8. The GA release of Virtual Threads fundamentally changed Java&#8217;s concurrency programming model.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZDgV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZDgV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ZDgV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ZDgV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ZDgV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZDgV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg" width="1313" height="551" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:551,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ZDgV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ZDgV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ZDgV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ZDgV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F890b9afe-e4a4-452b-a2c1-1ceec91e7242_1313x551.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Virtual Threads (JEP 444)</strong></p><p>Calling a Virtual Thread a &#8220;lightweight thread&#8221; doesn&#8217;t do it justice. Its essence is turning threads from an operating system resource into a JVM-managed resource.</p><p>Problems with traditional Platform Threads:</p><ul><li><p>Each thread occupies about 1 MB of stack memory (configurable; default <code>-Xss1m</code>)</p></li><li><p>Thread creation and destruction involve system calls (<code>pthread_create</code>/<code>pthread_exit</code>)</p></li><li><p>Context switching is expensive (kernel-mode switching)</p></li><li><p>The number of threads a single JVM process can create is usually in the thousands to tens of thousands</p></li></ul><p>How Virtual Threads are implemented:</p><ul><li><p>Managed by the JVM, not directly mapped to OS threads</p></li><li><p>Use Continuations to save and restore execution state</p></li><li><p>On blocking operations (I/O, sleep, locks, etc.), automatically unmount from the carrier thread</p></li><li><p>When the block clears, scheduled to continue on any available carrier thread</p></li><li><p>Stack space grows on demand, starting at only a few hundred bytes</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;f3578101-f5af-4f76-9ed9-c058f4dc2062&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Three ways to create a Virtual Thread
// Way 1: Thread.startVirtualThread
Thread vt = Thread.startVirtualThread(() -&gt; {
    System.out.println(&#8221;Running in virtual thread: &#8220; + Thread.currentThread());
});

// Way 2: Thread.ofVirtual()
Thread vt2 = Thread.ofVirtual()
    .name(&#8221;my-vt-&#8221;, 0)
    .start(() -&gt; doWork());

// Way 3: ExecutorService (recommended for production)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    // One virtual thread per task; no thread pool needed
    IntStream.range(0, 100_000).forEach(i -&gt; {
        executor.submit(() -&gt; {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}</code></pre></div><p>Performance comparison: 100,000 concurrent tasks</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;5c823efa-d3f6-47e0-84eb-cca9c4ea382b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class VirtualThreadBenchmark {

static final int TASK_COUNT = 100_000;
    public static void main(String[] args) throws Exception {
        // Platform Threads (pool limited to 200 threads)
        long startPlatform = System.nanoTime();
        try (var executor = Executors.newFixedThreadPool(200)) {
            var futures = IntStream.range(0, TASK_COUNT)
                .mapToObj(i -&gt; executor.submit(() -&gt; {
                    Thread.sleep(Duration.ofMillis(100));
                    return i;
                }))
                .toList();
            for (var f : futures) f.get();
        }
        long platformTime = System.nanoTime() - startPlatform;
        // Virtual Threads
        long startVirtual = System.nanoTime();
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            var futures = IntStream.range(0, TASK_COUNT)
                .mapToObj(i -&gt; executor.submit(() -&gt; {
                    Thread.sleep(Duration.ofMillis(100));
                    return i;
                }))
                .toList();
            for (var f : futures) f.get();
        }
        long virtualTime = System.nanoTime() - startVirtual;
        System.out.printf(&#8221;Platform Threads (200 pool): %.2f seconds%n&#8221;,
            platformTime / 1_000_000_000.0);
        System.out.printf(&#8221;Virtual Threads:             %.2f seconds%n&#8221;,
            virtualTime / 1_000_000_000.0);
    }
}
// Typical output:
// Platform Threads (200 pool): 50.12 seconds
// Virtual Threads:              0.15 seconds</code></pre></div><p>The core reason for this gap: 200 Platform Threads executing 100,000 blocking tasks of 100 ms each takes at least 100000 / 200 * 0.1 = 50 seconds. Virtual Threads, on the other hand, can create 100,000 threads at once; all tasks start sleeping at almost the same time and finish almost simultaneously 0.1 seconds later.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xDFd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xDFd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xDFd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xDFd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xDFd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xDFd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg" width="1313" height="375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:375,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xDFd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xDFd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xDFd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xDFd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9aa891-a5fa-485f-840a-b512fc6c1091_1313x375.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above directly compares the core differences between platform threads and virtual threads &#8212; platform threads are bound to OS threads (heavyweight, 1 MB stack), virtual threads are scheduled by the JVM (lightweight, KB-level), and on I/O blocking they automatically unmount from the carrier thread.</p><p><strong>Pitfalls of Virtual Threads</strong></p><p>When using Virtual Threads in production, watch out for the following:</p><ul><li><p>I/O inside <code>synchronized</code> blocks causes pinning: a Virtual Thread executing a blocking operation inside a <code>synchronized</code> block cannot unmount from its carrier thread. JDK 24 solves this via JEP 491, but you need to be careful on JDK 21.</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a358fae4-204c-4654-a73b-dc9c784b2af3&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Causes pinning on JDK 21 (not recommended)
synchronized (lock) {
    connection.read(); // Virtual thread is pinned to the carrier thread
}

// Prefer ReentrantLock instead
private final ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
    connection.read(); // no pinning
} finally {
    lock.unlock();
}</code></pre></div><ul><li><p>Don&#8217;t pool Virtual Threads: the design philosophy of Virtual Threads is &#8220;one task, one thread.&#8221; Managing Virtual Threads with a thread pool is an anti-pattern.</p></li><li><p>ThreadLocal memory issues: every Virtual Thread has its own ThreadLocal copy. If you create a million Virtual Threads and each holds ThreadLocal data, memory overhead becomes significant. JDK 21 introduces Scoped Values (preview) as a replacement.</p></li></ul><p><strong>Pattern Matching for switch (JEP 441)</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;f999a716-9abb-4b45-b89d-e15bb18f4e76&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Combined with sealed classes, the compiler performs exhaustive checks
public static double calculateArea(Shape shape) {
    return switch (shape) {
        case Circle c    -&gt; Math.PI * c.radius() * c.radius();
        case Rectangle r -&gt; r.width() * r.height();
        case Triangle t  -&gt; 0.5 * t.base() * t.height();
        // No default needed: all subclasses of the sealed interface are covered
    };
}

// Pattern matching with guards
public static String classify(Shape shape) {
    return switch (shape) {
        case Circle c when c.radius() &gt; 100   -&gt; &#8220;big circle&#8221;;
        case Circle c                          -&gt; &#8220;small circle&#8221;;
        case Rectangle r when r.width() == r.height() -&gt; &#8220;square&#8221;;
        case Rectangle r                       -&gt; &#8220;rectangle&#8221;;
        case Triangle t                        -&gt; &#8220;triangle&#8221;;
    };
}</code></pre></div><p><strong>Record Patterns (JEP 440)</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k5AV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k5AV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 424w, https://substackcdn.com/image/fetch/$s_!k5AV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 848w, https://substackcdn.com/image/fetch/$s_!k5AV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!k5AV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k5AV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg" width="1313" height="430" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:430,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!k5AV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 424w, https://substackcdn.com/image/fetch/$s_!k5AV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 848w, https://substackcdn.com/image/fetch/$s_!k5AV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!k5AV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54466b99-accc-45a5-823e-81d25e3e2394_1313x430.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above shows the full evolution of pattern matching from JDK 14&#8217;s instanceof pattern to JDK 21&#8217;s Record destructuring and switch pattern matching.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;8b30fdcf-0147-4e6b-a935-3921d3b5f36c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">record Point(int x, int y) {}
record Line(Point start, Point end) {}

// Nested destructuring
static void printLength(Object obj) {
    if (obj instanceof Line(Point(var x1, var y1), Point(var x2, var y2))) {
        double length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
        System.out.printf(&#8221;Line length: %.2f%n&#8221;, length);
    }
}</code></pre></div><p><strong>Sequenced Collections (JEP 431)</strong></p><p>Before JDK 21, getting the last element of a <code>LinkedHashSet</code> meant iterating the whole collection. The new interfaces unify operations on ordered collections:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;5c2b4401-32a7-4c25-ba56-f3b4ae0da7b4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">SequencedCollection&lt;String&gt; seq = new LinkedHashSet&lt;&gt;(List.of(&#8221;a&#8221;, &#8220;b&#8221;, &#8220;c&#8221;));
String first = seq.getFirst();    // &#8220;a&#8221;
String last = seq.getLast();      // &#8220;c&#8221;
SequencedCollection&lt;String&gt; reversed = seq.reversed();  // [&#8221;c&#8221;, &#8220;b&#8221;, &#8220;a&#8221;]


SequencedMap&lt;String, Integer&gt; seqMap = new LinkedHashMap&lt;&gt;();
seqMap.put(&#8221;one&#8221;, 1);
seqMap.put(&#8221;two&#8221;, 2);
Map.Entry&lt;String, Integer&gt; firstEntry = seqMap.firstEntry();
Map.Entry&lt;String, Integer&gt; lastEntry = seqMap.lastEntry();</code></pre></div><h3><strong>2.6 The JDK 22&#8211;24 Transition</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!swvP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!swvP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 424w, https://substackcdn.com/image/fetch/$s_!swvP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 848w, https://substackcdn.com/image/fetch/$s_!swvP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!swvP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!swvP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg" width="1313" height="466" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:466,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!swvP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 424w, https://substackcdn.com/image/fetch/$s_!swvP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 848w, https://substackcdn.com/image/fetch/$s_!swvP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!swvP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc225102a-2c56-4f26-baea-df7f7d838eb0_1313x466.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above shows the evolution of switch from the traditional JDK 8 statement to JDK 21&#8217;s full pattern matching &#8212; from fall-through semantics requiring break, to arrow syntax, yield expressions, and finally type patterns with guard conditions.</p><ul><li><p>JDK 22: unnamed variables and patterns <code>_</code> (JEP 456), statements allowed before <code>super(...)</code> (preview, JEP 447)</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;7bcad813-9245-4362-81b3-3cc1316f40fd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Unnamed variables
try {
    int result = Integer.parseInt(input);
} catch (NumberFormatException _) {
    System.out.println(&#8221;Invalid number&#8221;);
}

// Unnamed patterns in switch
switch (shape) {
    case Circle _   -&gt; System.out.println(&#8221;It&#8217;s a circle&#8221;);
    case Rectangle _ -&gt; System.out.println(&#8221;It&#8217;s a rectangle&#8221;);
    default -&gt; {}
}</code></pre></div><ul><li><p>JDK 23: primitive type pattern matching (preview, JEP 455), Markdown documentation comments (JEP 467)</p></li><li><p>JDK 24: Stream Gatherers finalized (JEP 485), Class-File API finalized (JEP 484), AOT class loading and linking (JEP 483), virtual threads without synchronized pinning (JEP 491)</p></li></ul><p>Stream Gatherers is one of the most practical new features of JDK 24:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;0a1e1c7d-ec62-408c-8e42-090b5595ff2e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 24: custom intermediate operations
// Example: sliding window
List&lt;List&lt;Integer&gt;&gt; windows = Stream.of(1, 2, 3, 4, 5)
    .gather(Gatherers.windowSliding(3))
    .toList();
// Result: [[1, 2, 3], [2, 3, 4], [3, 4, 5]]


// Example: fixed-size grouping
List&lt;List&lt;Integer&gt;&gt; groups = Stream.of(1, 2, 3, 4, 5)
    .gather(Gatherers.windowFixed(2))
    .toList();
// Result: [[1, 2], [3, 4], [5]]</code></pre></div><h3><strong>2.7 JDK 25: The Latest Features</strong></h3><p>JDK 25 was released on September 16, 2025, with 18 JEPs, 7 of which moved from preview/incubator to final features.</p><p><strong>Compact Object Headers (JEP 519, final)</strong></p><p>This is the core achievement of Project Lilliput. On 64-bit JVMs, each Java object header is compressed from 96&#8211;128 bits down to 64 bits (8 bytes). Measurements show heap memory usage drops 10&#8211;20%, and some benchmarks show 8% less CPU time.</p><pre><code><span># Enable Compact Object Headers (must be explicitly enabled in JDK 25)
java -XX:+UseCompactObjectHeaders -jar myapp.jar

# Inspect object layout (with the JOL tool)
# Before: 12-byte header (8B mark word + 4B compressed klass pointer)
# After:  8-byte header (mark word + class pointer merged)</span></code></pre><p>How it works: the class pointer is compressed from 32 bits to 22 bits and stored together with the mark word in a single 64-bit word. This means the maximum number of supported classes drops from 2&#179;&#178; to roughly 4 million (2&#178;&#178;) &#8212; plenty for the vast majority of applications.</p><p><strong>Scoped Values (JEP 506, final)</strong></p><p>Scoped Values are the modern replacement for ThreadLocal, especially suited to Virtual Threads:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iZVt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iZVt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 424w, https://substackcdn.com/image/fetch/$s_!iZVt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 848w, https://substackcdn.com/image/fetch/$s_!iZVt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 1272w, https://substackcdn.com/image/fetch/$s_!iZVt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iZVt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png" width="1313" height="409" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:409,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!iZVt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 424w, https://substackcdn.com/image/fetch/$s_!iZVt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 848w, https://substackcdn.com/image/fetch/$s_!iZVt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 1272w, https://substackcdn.com/image/fetch/$s_!iZVt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9cb11bd-74d8-4e69-9cdc-ad1f426d8930_1313x409.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above shows the core design of Structured Concurrency &#8212; a parent task forks subtasks, and when any subtask fails the remaining siblings are automatically cancelled, dramatically simplifying concurrency control and error handling compared with the traditional independent-thread model.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;2fbac98d-eb1a-4cf8-aa4b-02f8c4a76898&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Define a ScopedValue
private static final ScopedValue&lt;UserContext&gt; CURRENT_USER = ScopedValue.newInstance();

// Bind it at the request entry point
public void handleRequest(HttpRequest request) {
    UserContext ctx = authenticate(request);
    ScopedValue.runWhere(CURRENT_USER, ctx, () -&gt; {
        // Within this scope, any code can read CURRENT_USER
        processRequest(request);
    });
    // The scope ends and the value is released automatically; no memory leak risk
}
// Read it deep in the call chain
public void processRequest(HttpRequest request) {
    UserContext user = CURRENT_USER.get(); // read the value of the current scope
    // ...
}</code></pre></div><p>The essential differences from ThreadLocal:</p><ul><li><p>ScopedValue is immutable; ThreadLocal can be set at any time</p></li><li><p>ScopedValue has a well-defined lifetime (the scope); ThreadLocal requires manual <code>remove</code></p></li><li><p>Inheriting a ScopedValue in a Virtual Thread costs nothing; ThreadLocal must be copied</p></li></ul><p><strong>Flexible Constructor Bodies (JEP 513, final)</strong></p><p>Finally, statements are allowed before <code>super()</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;47005850-0639-4364-997a-11bc5e40a8bf&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class ValidatedOrder extends Order {
    public ValidatedOrder(String orderId, BigDecimal amount) {
        // JDK 25: validation and field initialization before super()
        if (orderId == null || orderId.isBlank()) {
            throw new IllegalArgumentException(&#8221;orderId cannot be empty&#8221;);
        }
        if (amount.compareTo(BigDecimal.ZERO) &lt;= 0) {
            throw new IllegalArgumentException(&#8221;amount must be positive&#8221;);
        }
        this.validatedAt = Instant.now(); // fields may be initialized
        super(orderId, amount); // then call the parent constructor
    }
}</code></pre></div><p><strong>Module Import Declarations (JEP 511, final)</strong></p><pre><code><span>// JDK 25: module-level import
import module java.base;  // imports all public types of the java.base module

// No more writing a pile of import java.util.*, import java.io.*, etc.
public class Demo {
    public static void main(String[] args) {
        var list = List.of(1, 2, 3);  // java.util.List
        var path = Path.of(&#8221;/tmp&#8221;);    // java.nio.file.Path
    }
}</span></code></pre><p><strong>Compact Source Files and Instance Main Methods (JEP 512, final)</strong></p><pre><code><span>// JDK 25: the simplest Hello World
void main() {
    println(&#8221;Hello, World!&#8221;);
}
// No public class, no static, no String[] args needed</span></code></pre><p><strong>Generational Shenandoah (JEP 521, final)</strong></p><p>Shenandoah GC gains generational support. Similar to Generational ZGC, it separates young and old generation collection to improve throughput and reduce pause times.</p><p><strong>Stable Values (JEP 502, preview)</strong></p><p>Stable Values are a mechanism between final fields and ordinary fields: they allow lazy initialization while still letting the JVM treat them as constants for optimization:</p><pre><code><span>// JDK 25 Preview
private final StableValue&lt;DatabaseConnection&gt; connection = StableValue.of();

public DatabaseConnection getConnection() {
    return connection.orElseSet(this::createConnection);
    // Initialized on first call; afterwards the JVM can treat it as a constant
}</span></code></pre><p><strong>AOT Method Profiling (JEP 515)</strong></p><p>Part of Project Leyden: saves method-level profiling data and reuses it on subsequent startups to accelerate JIT warm-up:</p><pre><code><span># First run: collect profiling data
java -XX:AOTConfiguration=app.aotconf -jar myapp.jar
# Second run: reuse the profiling data to speed up
java -XX:AOTConfiguration=app.aotconf -jar myapp.jar</span></code></pre><h2><strong>3. GC Garbage Collector Evolution</strong></h2><p>GC evolution is the most direct source of performance gains in JDK upgrades. The four LTS releases span Java GC&#8217;s journey from &#8220;usable&#8221; to &#8220;extreme.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ww0a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ww0a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ww0a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ww0a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ww0a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ww0a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg" width="1313" height="319" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:319,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ww0a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ww0a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ww0a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ww0a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F100a26de-9235-4563-8fcf-934790e5c511_1313x319.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong>3.1 JDK 8: G1 Becomes an Option, CMS Is Still Mainstream</strong></h3><p>JDK 8&#8217;s default GC is Parallel GC (also called the Throughput Collector), suited to throughput-first batch scenarios. However, most web applications chose CMS or G1:</p><pre><code><span># Common JDK 8 GC configurations
# CMS (low-latency priority)
java -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled \
     -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly \
     -Xms4g -Xmx4g -jar myapp.jar

# G1 (balanced)
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
     -XX:G1HeapRegionSize=8m -XX:InitiatingHeapOccupancyPercent=45 \
     -Xms4g -Xmx4g -jar myapp.jar</span></code></pre><p>The main pain points of GC in the JDK 8 era:</p><ul><li><p>CMS has the risk of concurrent mode failure; after triggering a Full GC, pauses can reach several seconds</p></li><li><p>CMS produces memory fragmentation; long-running processes need restarts</p></li><li><p>G1 wasn&#8217;t mature on JDK 8, and Full GC was single-threaded (only became multi-threaded in JDK 10)</p></li><li><p>PermGen space needs separate tuning, and OOMs were frequent</p></li></ul><h3><strong>3.2 JDK 17: G1 Matures, ZGC Goes into Production</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mnl8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mnl8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 424w, https://substackcdn.com/image/fetch/$s_!Mnl8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 848w, https://substackcdn.com/image/fetch/$s_!Mnl8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 1272w, https://substackcdn.com/image/fetch/$s_!Mnl8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mnl8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png" width="1313" height="614" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:614,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Mnl8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 424w, https://substackcdn.com/image/fetch/$s_!Mnl8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 848w, https://substackcdn.com/image/fetch/$s_!Mnl8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 1272w, https://substackcdn.com/image/fetch/$s_!Mnl8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd746f9b1-0f08-4762-b2d0-bfdce367e71f_1313x614.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above shows G1&#8217;s region-based heap layout and its four-phase workflow &#8212; Young GC (evacuate Eden/Survivor) &#8594; concurrent marking &#8594; Mixed GC (reclaim some Old regions) &#8594; Full GC (fallback).</p><p>By JDK 17, the GC landscape had changed significantly:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zfhE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zfhE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 424w, https://substackcdn.com/image/fetch/$s_!zfhE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 848w, https://substackcdn.com/image/fetch/$s_!zfhE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 1272w, https://substackcdn.com/image/fetch/$s_!zfhE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zfhE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png" width="1313" height="434" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:434,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!zfhE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 424w, https://substackcdn.com/image/fetch/$s_!zfhE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 848w, https://substackcdn.com/image/fetch/$s_!zfhE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 1272w, https://substackcdn.com/image/fetch/$s_!zfhE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F307dd4e2-6d28-436b-8067-74ab303182ae_1313x434.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>G1 on JDK 17 is a qualitative leap compared with JDK 8:</p><ul><li><p>NUMA-aware memory allocation (JDK 14, JEP 345)</p></li><li><p>Interruptible Mixed GC (JDK 12, JEP 344)</p></li><li><p>Parallel Full GC (JDK 10, JEP 307)</p></li><li><p>Automatically returns unused heap memory to the OS (JDK 12, JEP 346)</p></li></ul><pre><code><span># Recommended G1 configuration on JDK 17
java -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=100 \
     -XX:G1HeapRegionSize=16m \
     -XX:G1NewSizePercent=20 \
     -XX:G1MaxNewSizePercent=40 \
     -XX:G1ReservePercent=15 \
     -XX:InitiatingHeapOccupancyPercent=35 \
     -Xms8g -Xmx8g -jar myapp.jar

# JDK 17 ZGC configuration (for ultra-low-latency scenarios)
java -XX:+UseZGC \
     -XX:ZCollectionInterval=5 \
     -XX:SoftMaxHeapSize=6g \
     -Xms8g -Xmx8g -jar myapp.jar</span></code></pre><h3><strong>3.3 JDK 21: Generational ZGC</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NIkp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NIkp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 424w, https://substackcdn.com/image/fetch/$s_!NIkp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 848w, https://substackcdn.com/image/fetch/$s_!NIkp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 1272w, https://substackcdn.com/image/fetch/$s_!NIkp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NIkp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png" width="1313" height="371" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:371,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NIkp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 424w, https://substackcdn.com/image/fetch/$s_!NIkp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 848w, https://substackcdn.com/image/fetch/$s_!NIkp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 1272w, https://substackcdn.com/image/fetch/$s_!NIkp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6773f1-4b0b-4dd3-83d1-625f013f2e34_1313x371.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>JDK 21 introduced Generational ZGC (JEP 439), a major upgrade to ZGC.</p><p>Why does ZGC need generations?</p><p>ZGC was originally non-generational, managing all objects uniformly. That means every GC must scan the entire heap. Although pause times are very short (sub-millisecond), the scanning overhead is high and throughput suffers. With generations:</p><ul><li><p>Young generation collects frequently, with a small scope and high speed</p></li><li><p>Old generation collects rarely, greatly reducing scanning overhead</p></li><li><p>Overall throughput improves 10&#8211;20%</p></li></ul><pre><code><span># JDK 21 generational ZGC
java -XX:+UseZGC -XX:+ZGenerational \
     -Xms16g -Xmx16g -jar myapp.jar</span></code></pre><p>Measured data (an e-commerce order pipeline, 16 G heap, 8 cores):</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IZ7O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IZ7O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 424w, https://substackcdn.com/image/fetch/$s_!IZ7O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 848w, https://substackcdn.com/image/fetch/$s_!IZ7O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 1272w, https://substackcdn.com/image/fetch/$s_!IZ7O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IZ7O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png" width="1313" height="196" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:196,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!IZ7O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 424w, https://substackcdn.com/image/fetch/$s_!IZ7O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 848w, https://substackcdn.com/image/fetch/$s_!IZ7O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 1272w, https://substackcdn.com/image/fetch/$s_!IZ7O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f37a87-777e-4a52-b5db-b03b7442b9bf_1313x196.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>As you can see, generational ZGC not only keeps pauses extremely low, it also pushes throughput above G1.</p><h3><strong>3.4 JDK 25: Further GC Optimization</strong></h3><p>JDK 25&#8217;s GC changes:</p><ul><li><p>Generational Shenandoah (JEP 521, final): like ZGC, Shenandoah gains generational support. Introduced as experimental in JDK 24 and finalized in JDK 25.</p></li><li><p>Non-generational ZGC removed (JDK 24, JEP 490): starting with JDK 24, ZGC only has generational mode; <code>-XX:+ZGenerational</code> is no longer needed (nor accepted), and generational is the default.</p></li><li><p>Compact Object Headers (JEP 519) impact on GC: a smaller object header means less metadata for every GC to process, making the mark phase faster.</p></li></ul><pre><code><span># Recommended ZGC configuration on JDK 25
java -XX:+UseZGC \
     -XX:+UseCompactObjectHeaders \
     -Xms16g -Xmx16g -jar myapp.jar

# JDK 25 Shenandoah generational mode
java -XX:+UseShenandoahGC \
     -XX:ShenandoahGCMode=generational \
     -Xms16g -Xmx16g -jar myapp.jar</span></code></pre><h3><strong>3.5 GC Selection Guide</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4J9u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4J9u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 424w, https://substackcdn.com/image/fetch/$s_!4J9u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 848w, https://substackcdn.com/image/fetch/$s_!4J9u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 1272w, https://substackcdn.com/image/fetch/$s_!4J9u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4J9u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png" width="1313" height="275" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:275,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!4J9u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 424w, https://substackcdn.com/image/fetch/$s_!4J9u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 848w, https://substackcdn.com/image/fetch/$s_!4J9u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 1272w, https://substackcdn.com/image/fetch/$s_!4J9u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F153bd057-11ed-498d-936c-f8d7573ea37a_1313x275.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uFdF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uFdF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 424w, https://substackcdn.com/image/fetch/$s_!uFdF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 848w, https://substackcdn.com/image/fetch/$s_!uFdF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 1272w, https://substackcdn.com/image/fetch/$s_!uFdF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uFdF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png" width="1313" height="811" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:811,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!uFdF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 424w, https://substackcdn.com/image/fetch/$s_!uFdF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 848w, https://substackcdn.com/image/fetch/$s_!uFdF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 1272w, https://substackcdn.com/image/fetch/$s_!uFdF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7d726fc-425d-4d89-842d-7e5ef61ac73b_1313x811.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A real GC migration case:</p><p>We had an order service on JDK 8 + CMS with an 8 G heap. Every afternoon during peak traffic, CMS would frequently hit concurrent mode failure, trigger Full GC, pause for 3&#8211;5 seconds, and directly cause timeouts at the upstream gateway.</p><p>After migrating to JDK 17 + G1, P99 GC pauses dropped below 50 ms and concurrent mode failure disappeared entirely. Later we upgraded further to JDK 21 + Generational ZGC + 16 G heap, where P99 fell to 0.5 ms &#8212; business code essentially can&#8217;t perceive GC anymore.</p><h2><strong>4. Performance Optimization and JIT Compilation</strong></h2><h3><strong>4.1 JIT Compiler Evolution</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DQT0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DQT0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 424w, https://substackcdn.com/image/fetch/$s_!DQT0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 848w, https://substackcdn.com/image/fetch/$s_!DQT0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 1272w, https://substackcdn.com/image/fetch/$s_!DQT0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DQT0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png" width="1313" height="474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:474,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DQT0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 424w, https://substackcdn.com/image/fetch/$s_!DQT0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 848w, https://substackcdn.com/image/fetch/$s_!DQT0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 1272w, https://substackcdn.com/image/fetch/$s_!DQT0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd971fa27-46c2-43c3-9fa0-58dea003cef1_1313x474.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The JDK&#8217;s JIT (Just-In-Time) compiler compiles hot bytecode into machine code. Understanding JIT&#8217;s evolution is critical for performance tuning.</p><p><strong>Tiered compilation in JDK 8</strong></p><p>JDK 8 uses two compilers, C1 (Client Compiler) and C2 (Server Compiler), cooperating through tiered compilation:</p><ul><li><p>Level 0: interpreted execution</p></li><li><p>Level 1: C1 compilation, no profiling</p></li><li><p>Level 2: C1 compilation, limited profiling</p></li><li><p>Level 3: C1 compilation, full profiling</p></li><li><p>Level 4: C2 compilation (final optimized code)</p></li></ul><pre><code><span># JDK 8: view JIT compilation logs
java -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions \
     -XX:+PrintInlining -jar myapp.jar</span></code></pre><p><strong>The Graal compiler experiment of JDK 10&#8211;17</strong></p><p>JDK 10 introduced Graal as an experimental JIT compiler (JEP 317), written in Java and theoretically easier to maintain and extend. But JDK 17 removed the Graal JIT interfaces (JEP 410) because Oracle shifted Graal&#8217;s development focus to the GraalVM project.</p><p><strong>Continuous C2 optimization in JDK 21&#8211;25</strong></p><p>No new JIT compiler was introduced, but C2 has been continuously improved version by version:</p><ul><li><p>Better auto-vectorization</p></li><li><p>Enhanced escape analysis, with more objects allocated on the stack</p></li><li><p>More intrinsic methods; common operations map directly to CPU instructions</p></li></ul><h3><strong>4.2 Startup Speed Optimization</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Vk_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Vk_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 424w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 848w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1272w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png" width="1313" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-Vk_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 424w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 848w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1272w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Startup speed is critical in serverless and containerized scenarios. Startup optimization across versions:</p><p><strong>CDS (Class Data Sharing) evolution</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aDU4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aDU4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 424w, https://substackcdn.com/image/fetch/$s_!aDU4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 848w, https://substackcdn.com/image/fetch/$s_!aDU4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 1272w, https://substackcdn.com/image/fetch/$s_!aDU4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aDU4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png" width="1313" height="310" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:310,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!aDU4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 424w, https://substackcdn.com/image/fetch/$s_!aDU4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 848w, https://substackcdn.com/image/fetch/$s_!aDU4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 1272w, https://substackcdn.com/image/fetch/$s_!aDU4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65d075a4-97b1-40fa-8bae-07aee76dd564_1313x310.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><pre><code><span># JDK 17: dynamic CDS
# First run, generate the archive
java -XX:ArchiveClassesAtExit=app-cds.jsa -jar myapp.jar
# Subsequent runs, use the archive
java -XX:SharedArchiveFile=app-cds.jsa -jar myapp.jar
# Startup improves 20-40%

# JDK 24+: AOT class loading and linking
java -XX:AOTCache=app.aot -XX:AOTConfiguration=app.aotconf -jar myapp.jar
# Startup can improve up to 40-60%</span></code></pre><p>Measured startup times (Spring Boot 3.x application, medium size, 50 beans):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M4tC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M4tC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 424w, https://substackcdn.com/image/fetch/$s_!M4tC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 848w, https://substackcdn.com/image/fetch/$s_!M4tC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 1272w, https://substackcdn.com/image/fetch/$s_!M4tC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M4tC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png" width="1066" height="412" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:412,&quot;width&quot;:1066,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!M4tC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 424w, https://substackcdn.com/image/fetch/$s_!M4tC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 848w, https://substackcdn.com/image/fetch/$s_!M4tC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 1272w, https://substackcdn.com/image/fetch/$s_!M4tC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56a42d1-f3d5-4219-b105-04b119805efd_1066x412.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>4.3 Memory Model Changes</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Vk_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Vk_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 424w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 848w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1272w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png" width="1313" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-Vk_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 424w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 848w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1272w, https://substackcdn.com/image/fetch/$s_!-Vk_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F881ce7a0-79bf-4aee-a318-a6ebf9c9fc4b_1313x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Compact Strings (JDK 9, JEP 254)</strong></p><p>JDK 8&#8217;s String internally uses <code>char[]</code> (2 bytes per character, UTF-16). JDK 9 changed it to <code>byte[]</code> + an encoding flag, so Latin-1 strings use only 1 byte per character:</p><pre><code><span>// JDK 8: String internals
private final char[] value; // 2 bytes per character

// JDK 9+: String internals
private final byte[] value; // 1 byte per character for Latin-1
private final byte coder;   // 0 = Latin-1, 1 = UTF-16</span></code></pre><p>For applications that are mostly English and numbers (most backend services), String memory usage is cut in half. One of our log-analysis services dropped its heap usage from 6 G to 4.2 G after upgrading to JDK 11.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DzjZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DzjZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 424w, https://substackcdn.com/image/fetch/$s_!DzjZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 848w, https://substackcdn.com/image/fetch/$s_!DzjZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 1272w, https://substackcdn.com/image/fetch/$s_!DzjZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DzjZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png" width="1313" height="569" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/354c7514-f007-4670-82c8-72dbfd231329_1313x569.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:569,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DzjZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 424w, https://substackcdn.com/image/fetch/$s_!DzjZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 848w, https://substackcdn.com/image/fetch/$s_!DzjZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 1272w, https://substackcdn.com/image/fetch/$s_!DzjZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F354c7514-f007-4670-82c8-72dbfd231329_1313x569.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above illustrates the memory optimization of Compact Strings (JEP 254) &#8212; JDK 8&#8217;s <code>char[]</code> is a fixed 2 bytes per character, while JDK 9+&#8217;s <code>byte[]</code> + coder needs only 1 byte per Latin-1 character, halving memory in English-heavy scenarios.</p><p><strong>PermGen &#8594; Metaspace</strong></p><p>JDK 8 replaced PermGen with Metaspace (native memory, not heap memory):</p><ul><li><p>No more <code>java.lang.OutOfMemoryError: PermGen space</code></p></li><li><p>No upper limit by default (configurable via <code>-XX:MaxMetaspaceSize</code>)</p></li><li><p>More efficient class unloading</p></li></ul><p><strong>The memory impact of JDK 25 Compact Object Headers</strong></p><p>Minimum size of a Java object:</p><ul><li><p>JDK 8&#8211;24 (with compressed pointers): 12 B header + alignment padding = 16 B</p></li><li><p>JDK 25 (Compact Headers): 8 B header + alignment padding = 16 B (still 16 B minimum due to alignment)</p></li></ul><p>But for slightly larger objects (with 1&#8211;2 fields), the difference shows:</p><pre><code><span>// An object with one int field
// JDK 8-24:  header(12B) + int(4B) = 16B
// JDK 25:    header(8B) + int(4B) + padding(4B) = 16B
// No difference in this case
// An object with int + boolean fields
// JDK 8-24:  header(12B) + int(4B) + boolean(1B) + padding(7B) = 24B
// JDK 25:    header(8B) + int(4B) + boolean(1B) + padding(3B) = 16B
// Saves 8B (33%)</span></code></pre><p>When your application has lots of small objects (DTOs, Events, Node nodes), the gains from Compact Object Headers are significant.</p><h2><strong>5. The Module System (JPMS)</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!luYB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!luYB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 424w, https://substackcdn.com/image/fetch/$s_!luYB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 848w, https://substackcdn.com/image/fetch/$s_!luYB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!luYB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!luYB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg" width="1313" height="588" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:588,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!luYB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 424w, https://substackcdn.com/image/fetch/$s_!luYB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 848w, https://substackcdn.com/image/fetch/$s_!luYB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!luYB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c4031c8-e0f0-4f38-83c6-be8909ecd721_1313x588.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>JPMS (Java Platform Module System) is the core deliverable of Project Jigsaw introduced in JDK 9. To be blunt: as of 2025, most business projects still don&#8217;t use the module system. But it&#8217;s important to understand, because it affects access control over JDK internal APIs and many migration issues.</p><p>Basic structure of module-info.java:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;7b45a5e5-ccf3-45de-940c-22135f21d508&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">module com.myapp.order {
    // Declare dependencies
    requires java.sql;
    requires java.logging;
    requires transitive com.myapp.common; // transitive dependency

// Export packages (only exported packages are accessible to other modules)
    exports com.myapp.order.api;
    exports com.myapp.order.model;
    // Open reflection to specific modules (for frameworks such as Jackson, Hibernate)
    opens com.myapp.order.entity to com.fasterxml.jackson.databind;
    opens com.myapp.order.entity to org.hibernate.orm.core;
    // SPI service declarations
    provides com.myapp.common.spi.PaymentProvider
        with com.myapp.order.payment.AlipayProvider;
    uses com.myapp.common.spi.NotificationService;
}</code></pre></div><p>Why don&#8217;t most projects use modules?</p><ul><li><p>Spring Framework&#8217;s compatibility strategy: Spring relies heavily on reflection and dynamic proxies, which conflict with the module system&#8217;s strong encapsulation. Although Spring 5+ provides <code>Automatic-Module-Name</code>, full modularization has never been a priority.</p></li><li><p>Third-party libraries are poorly modularized: many common libraries are still unnamed or automatic modules, and mixing them easily leads to split-package problems.</p></li><li><p>Cost/benefit mismatch: for most business applications, package access control plus Maven/Gradle dependency management is enough; JPMS&#8217;s strong isolation doesn&#8217;t pay off.</p></li></ul><p>But JPMS&#8217;s impact on the JDK itself is profound:</p><p>Starting with JDK 16, the <code>--illegal-access</code> option was removed and JDK internal APIs are strongly encapsulated by default. If your code or dependencies directly use internal APIs like <code>sun.misc.Unsafe</code> or <code>com.sun.xml.internal.*</code>, you must handle them when upgrading:</p><pre><code><span># Temporary workaround: add --add-opens (not recommended long-term)
java --add-opens java.base/java.lang=ALL-UNNAMED \
     --add-opens java.base/sun.nio.ch=ALL-UNNAMED \
     -jar myapp.jar

# Correct approach: replace with public APIs
# sun.misc.Unsafe &#8594; VarHandle (JDK 9+)
# sun.misc.BASE64Encoder &#8594; java.util.Base64 (JDK 8+)
# sun.reflect.Reflection &#8594; StackWalker (JDK 9+)</span></code></pre><h2><strong>6. Core API Changes</strong></h2><h3><strong>6.1 Collection Factory Methods</strong></h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;7709ba62-e76c-41ac-b02f-0a80189515dc&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 8: creating immutable collections
List&lt;String&gt; list = Collections.unmodifiableList(Arrays.asList(&#8221;a&#8221;, &#8220;b&#8221;, &#8220;c&#8221;));
Map&lt;String, Integer&gt; map = Collections.unmodifiableMap(new HashMap&lt;&gt;() {{
    put(&#8221;one&#8221;, 1);
    put(&#8221;two&#8221;, 2);
}});

// JDK 9+: collection factory methods
List&lt;String&gt; list = List.of(&#8221;a&#8221;, &#8220;b&#8221;, &#8220;c&#8221;);
Set&lt;String&gt; set = Set.of(&#8221;a&#8221;, &#8220;b&#8221;, &#8220;c&#8221;);
Map&lt;String, Integer&gt; map = Map.of(&#8221;one&#8221;, 1, &#8220;two&#8221;, 2);
Map&lt;String, Integer&gt; mapFromEntries = Map.ofEntries(
    Map.entry(&#8221;one&#8221;, 1),
    Map.entry(&#8221;two&#8221;, 2),
    Map.entry(&#8221;three&#8221;, 3)
);
// JDK 10+: Collectors.toUnmodifiableList
List&lt;String&gt; filtered = list.stream()
    .filter(s -&gt; s.startsWith(&#8221;a&#8221;))
    .collect(Collectors.toUnmodifiableList());
// JDK 16+: Stream.toList() (returns an unmodifiable List)
List&lt;String&gt; filtered = list.stream()
    .filter(s -&gt; s.startsWith(&#8221;a&#8221;))
    .toList();
// JDK 21: SequencedCollection
SequencedCollection&lt;String&gt; seqList = new ArrayList&lt;&gt;(List.of(&#8221;a&#8221;, &#8220;b&#8221;, &#8220;c&#8221;));
seqList.addFirst(&#8221;z&#8221;);
seqList.addLast(&#8221;d&#8221;);
String first = seqList.getFirst(); // &#8220;z&#8221;
String last = seqList.getLast();   // &#8220;d&#8221;</code></pre></div><h3><strong>6.2 HttpClient</strong></h3><p>JDK 8&#8217;s <code>HttpURLConnection</code> is widely considered a terrible API. JDK 11 standardized the brand-new HttpClient (JEP 321).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zZ9K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zZ9K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 424w, https://substackcdn.com/image/fetch/$s_!zZ9K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 848w, https://substackcdn.com/image/fetch/$s_!zZ9K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 1272w, https://substackcdn.com/image/fetch/$s_!zZ9K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zZ9K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png" width="1313" height="548" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:548,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!zZ9K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 424w, https://substackcdn.com/image/fetch/$s_!zZ9K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 848w, https://substackcdn.com/image/fetch/$s_!zZ9K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 1272w, https://substackcdn.com/image/fetch/$s_!zZ9K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56e37b37-5984-40c1-b447-1c0b8decced5_1313x548.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The diagram above compares the architecture of JDK 8&#8217;s <code>HttpURLConnection</code> (blocking, verbose, no HTTP/2) with JDK 11+&#8217;s HttpClient (async, HTTP/2, fluent API).</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;e00c5f7a-02e7-4e29-bcb3-9145796c7cd4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 8: HttpURLConnection (the painful way)
URL url = new URL(&#8221;https://api.example.com/users&#8221;);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(&#8221;GET&#8221;);
conn.setRequestProperty(&#8221;Accept&#8221;, &#8220;application/json&#8221;);
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);


int responseCode = conn.getResponseCode();
if (responseCode == 200) {
    try (BufferedReader br = new BufferedReader(
            new InputStreamReader(conn.getInputStream()))) {
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            response.append(line);
        }
        System.out.println(response.toString());
    }
} else {
    // error handling...
}
conn.disconnect();
// JDK 11+: HttpClient (the modern way)
HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .connectTimeout(Duration.ofSeconds(5))
    .followRedirects(HttpClient.Redirect.NORMAL)
    .build();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(&#8221;https://api.example.com/users&#8221;))
    .header(&#8221;Accept&#8221;, &#8220;application/json&#8221;)
    .timeout(Duration.ofSeconds(10))
    .GET()
    .build();
// Synchronous call
HttpResponse&lt;String&gt; response = client.send(request,
    HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// Asynchronous call
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println)
    .exceptionally(e -&gt; { e.printStackTrace(); return null; });
// POST JSON
HttpRequest postRequest = HttpRequest.newBuilder()
    .uri(URI.create(&#8221;https://api.example.com/users&#8221;))
    .header(&#8221;Content-Type&#8221;, &#8220;application/json&#8221;)
    .POST(HttpRequest.BodyPublishers.ofString(&#8221;&#8220;&#8221;
        {&#8221;name&#8221;: &#8220;Zhang San&#8221;, &#8220;email&#8221;: &#8220;zhangsan@example.com&#8221;}
        &#8220;&#8221;&#8220;))
    .build();</code></pre></div><h2><strong>6.3 Foreign Function &amp; Memory API</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fc0b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fc0b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Fc0b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Fc0b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Fc0b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fc0b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg" width="1313" height="403" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:403,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Fc0b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Fc0b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Fc0b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Fc0b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3980ba91-e99c-4892-a83a-0d6cb58a26aa_1313x403.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The FFM API (Foreign Function &amp; Memory API) is the core deliverable of Project Panama, aimed at replacing JNI (Java Native Interface). It started incubating in JDK 14 and was finalized in JDK 22.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;5e06d0be-29ed-4f14-ab89-8ed133fe2bf0&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 22+: call strlen from the C standard library via the FFM API
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;

public class FFMExample {
    public static void main(String[] args) throws Throwable {
        // Get the system linker
        Linker linker = Linker.nativeLinker();

        // Look up the strlen function in the C standard library
        SymbolLookup stdlib = linker.defaultLookup();
        MemorySegment strlenAddr = stdlib.find(&#8221;strlen&#8221;).orElseThrow();
        // Create a method handle
        MethodHandle strlen = linker.downcallHandle(
            strlenAddr,
            FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
        );
        // Allocate and use native memory
        try (Arena arena = Arena.ofConfined()) {
            MemorySegment cString = arena.allocateFrom(&#8221;Hello, FFM!&#8221;);
            long length = (long) strlen.invoke(cString);
            System.out.println(&#8221;String length: &#8220; + length); // prints: 11
        }
        // The Arena releases native memory automatically when closed; no leaks
    }
}</code></pre></div><p>Compared with JNI:</p><ul><li><p>Safety: the FFM API manages memory lifetimes at the Java level; JNI requires manual C memory management</p></li><li><p>Developer efficiency: the FFM API is pure Java; JNI requires writing C/C++ code plus header files</p></li><li><p>Performance: the FFM API performs on par with JNI, and is better in some cases (it avoids JNI&#8217;s boundary-crossing overhead)</p></li><li><p>Tooling: the jextract tool can auto-generate Java bindings from C header files</p></li></ul><h3><strong>6.4 Other Important API Changes</strong></h3><p><strong>Process API enhancements (JDK 9)</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;45fdf36f-da8c-4870-a24a-8594da3fb219&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 9+: get process information
ProcessHandle current = ProcessHandle.current();
System.out.println(&#8221;PID: &#8220; + current.pid());
System.out.println(&#8221;Command: &#8220; + current.info().command().orElse(&#8221;unknown&#8221;));
System.out.println(&#8221;CPU Duration: &#8220; + current.info().totalCpuDuration().orElse(Duration.ZERO));

// List all child processes
current.children().forEach(ph -&gt;
    System.out.println(&#8221;Child PID: &#8220; + ph.pid()));</code></pre></div><p><strong>CompletableFuture enhancements</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;fd8dc722-372e-455c-b6db-be19cc4fe17a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 9: orTimeout, completeOnTimeout
CompletableFuture&lt;String&gt; future = callRemoteService()
    .orTimeout(5, TimeUnit.SECONDS)          // throws TimeoutException after 5 seconds
    .completeOnTimeout(&#8221;default&#8221;, 5, TimeUnit.SECONDS); // returns a default value on timeout

// JDK 9: copy()
CompletableFuture&lt;String&gt; defensiveCopy = future.copy(); // prevents external code from completing it
// JDK 12: exceptionallyCompose
CompletableFuture&lt;String&gt; resilient = callPrimaryService()
    .exceptionallyCompose(ex -&gt; callFallbackService());</code></pre></div><p><strong>Ongoing Stream API enhancements</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;4dd52d4f-d19c-440c-807e-ae5e233e11a4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// JDK 9: takeWhile, dropWhile
Stream.of(1, 2, 3, 4, 5, 1, 2)
    .takeWhile(n -&gt; n &lt; 4)     // [1, 2, 3]
    .forEach(System.out::println);


// JDK 9: ofNullable
Stream&lt;String&gt; stream = Stream.ofNullable(getNullableValue()); // null-safe
// JDK 16: Stream.toList()
List&lt;Integer&gt; list = Stream.of(1, 2, 3).toList(); // replaces collect(Collectors.toList())
// JDK 16: mapMulti
Stream.of(1, 2, 3)
    .&lt;Integer&gt;mapMulti((num, consumer) -&gt; {
        consumer.accept(num);
        consumer.accept(num * 10);
    })
    .toList(); // [1, 10, 2, 20, 3, 30]</code></pre></div><h2><strong>7. Security Enhancements</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KaeN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KaeN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 424w, https://substackcdn.com/image/fetch/$s_!KaeN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 848w, https://substackcdn.com/image/fetch/$s_!KaeN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 1272w, https://substackcdn.com/image/fetch/$s_!KaeN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KaeN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png" width="1313" height="362" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:362,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!KaeN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 424w, https://substackcdn.com/image/fetch/$s_!KaeN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 848w, https://substackcdn.com/image/fetch/$s_!KaeN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 1272w, https://substackcdn.com/image/fetch/$s_!KaeN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ad157fd-87e7-4254-9969-3f9d6a4cd6b6_1313x362.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Security changes are often overlooked, but in production they can cause SSL handshake failures or make encryption algorithms unavailable right after an upgrade.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iWXQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iWXQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 424w, https://substackcdn.com/image/fetch/$s_!iWXQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 848w, https://substackcdn.com/image/fetch/$s_!iWXQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 1272w, https://substackcdn.com/image/fetch/$s_!iWXQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iWXQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png" width="1313" height="341" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:341,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!iWXQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 424w, https://substackcdn.com/image/fetch/$s_!iWXQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 848w, https://substackcdn.com/image/fetch/$s_!iWXQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 1272w, https://substackcdn.com/image/fetch/$s_!iWXQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a57418f-705a-4cca-a7b4-36784f9c3569_1313x341.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>JDK 25 security features worth special attention:</p><ul><li><p>Quantum-resistant algorithm ML-DSA: the Module-Lattice-Based Digital Signature Algorithm introduced in JDK 24, following the NIST FIPS 204 standard, preparing for the post-quantum computing era</p></li><li><p>Key Derivation Function API (JEP 506): a standardized key derivation function API</p></li><li><p>PEM Encodings (JEP 470, preview): PEM encoding support for cryptographic objects</p></li></ul><p>Security pitfalls when migrating:</p><pre><code><span># Problem: after upgrading from JDK 8 to JDK 17, connections to legacy SSL services fail
# Cause: JDK 17 disables TLS 1.0/1.1 and weak cipher algorithms by default
# Temporary workaround (not recommended long-term):
java -Djdk.tls.disabledAlgorithms=&#8221;&#8220; -jar myapp.jar

# Correct approach: upgrade the TLS configuration on the peer side</span></code></pre><p>The impact of strong encapsulation:</p><p>Starting with JDK 17, the <code>--illegal-access</code> option is completely removed. All reflective access to JDK internal APIs is denied by default. This directly affects frameworks such as Spring, Hibernate, and Lombok. Minimum supported versions:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Eknm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Eknm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 424w, https://substackcdn.com/image/fetch/$s_!Eknm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 848w, https://substackcdn.com/image/fetch/$s_!Eknm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 1272w, https://substackcdn.com/image/fetch/$s_!Eknm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Eknm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png" width="1313" height="305" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:305,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Eknm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 424w, https://substackcdn.com/image/fetch/$s_!Eknm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 848w, https://substackcdn.com/image/fetch/$s_!Eknm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 1272w, https://substackcdn.com/image/fetch/$s_!Eknm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa63bffa7-b0d4-4965-b40a-bfa0db22362b_1313x305.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2><strong>8. Production Migration Practice</strong></h2><h3><strong>8.1 JDK 8 &#8594; JDK 17 Migration</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DOO-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DOO-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 424w, https://substackcdn.com/image/fetch/$s_!DOO-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 848w, https://substackcdn.com/image/fetch/$s_!DOO-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 1272w, https://substackcdn.com/image/fetch/$s_!DOO-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DOO-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png" width="1313" height="216" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:216,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DOO-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 424w, https://substackcdn.com/image/fetch/$s_!DOO-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 848w, https://substackcdn.com/image/fetch/$s_!DOO-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 1272w, https://substackcdn.com/image/fetch/$s_!DOO-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3c1988d-75d8-4424-ab74-eada928fb592_1313x216.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This was the largest and most painful migration. Here are the main pitfalls our team hit:</p><p><strong>Step 1: Dependency analysis</strong></p><pre><code><span># Use jdeps to analyze your code&#8217;s dependencies on JDK internal APIs
jdeps --jdk-internals -R --class-path &#8216;libs/*&#8217; myapp.jar

# Example output:
# myapp.jar -&gt; java.base
#    com.myapp.util.UnsafeHelper -&gt; sun.misc.Unsafe  JDK internal API (jdk.unsupported)
#    com.myapp.xml.Parser -&gt; com.sun.org.apache.xerces.internal.jaxp JDK internal API</span></code></pre><p><strong>Step 2: Handle breaking changes</strong></p><p>Core issue checklist:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E5zk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E5zk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 424w, https://substackcdn.com/image/fetch/$s_!E5zk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 848w, https://substackcdn.com/image/fetch/$s_!E5zk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 1272w, https://substackcdn.com/image/fetch/$s_!E5zk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E5zk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png" width="1313" height="343" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:343,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!E5zk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 424w, https://substackcdn.com/image/fetch/$s_!E5zk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 848w, https://substackcdn.com/image/fetch/$s_!E5zk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 1272w, https://substackcdn.com/image/fetch/$s_!E5zk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27de635e-f1bf-49fd-8724-2e0cf6304a7b_1313x343.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Step 3: Spring Boot upgrade path</strong></p><p>If you use Spring Boot, the upgrade path is:</p><pre><code><span>Spring Boot 2.x (JDK 8)
  &#8594; Spring Boot 2.7.x (JDK 17 compatible mode)
  &#8594; Spring Boot 3.0+ (JDK 17 native support, javax &#8594; jakarta)</span></code></pre><p>The javax &#8594; jakarta migration in Spring Boot 3.0 is the biggest chunk of work. You can automate it with OpenRewrite:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;xml&quot;,&quot;nodeId&quot;:&quot;308bd1eb-d7f8-4d69-b818-153d8d33ec0b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-xml">&lt;!-- add the OpenRewrite plugin to pom.xml --&gt;
&lt;plugin&gt;
    &lt;groupId&gt;org.openrewrite.maven&lt;/groupId&gt;
    &lt;artifactId&gt;rewrite-maven-plugin&lt;/artifactId&gt;
    &lt;version&gt;5.37.0&lt;/version&gt;
    &lt;configuration&gt;
        &lt;activeRecipes&gt;
            &lt;recipe&gt;org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0&lt;/recipe&gt;
        &lt;/activeRecipes&gt;
    &lt;/configuration&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.openrewrite.recipe&lt;/groupId&gt;
            &lt;artifactId&gt;rewrite-spring&lt;/artifactId&gt;
            &lt;version&gt;5.16.0&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/plugin&gt;</code></pre></div><pre><code><span># Run the automated migration
mvn rewrite:run</span></code></pre><p><strong>Step 4: Clean up JVM arguments</strong></p><p>Many JDK 8 JVM arguments were removed or changed in JDK 17:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;0e41432e-68bb-4acf-a5ec-95c75d101a33&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext"># JDK 8 argument &#8594; how to handle it on JDK 17
-XX:+UseConcMarkSweepGC     &#8594; removed (CMS is gone), use -XX:+UseG1GC
-XX:+UseParNewGC             &#8594; removed, G1 handles it automatically
-XX:CMSInitiatingOccupancyFraction=75 &#8594; removed
-XX:+PrintGCDetails          &#8594; use -Xlog:gc*
-XX:+PrintGCDateStamps       &#8594; use -Xlog:gc*:time
-XX:+UseGCLogFileRotation    &#8594; use -Xlog:gc*:file=gc.log:time:filecount=5,filesize=10m
-XX:PermSize=256m            &#8594; removed (PermGen no longer exists)
-XX:MaxPermSize=512m         &#8594; removed (optionally -XX:MaxMetaspaceSize)


# Typical JDK 8 JVM arguments
java -Xms4g -Xmx4g \
     -XX:+UseConcMarkSweepGC \
     -XX:+CMSParallelRemarkEnabled \
     -XX:CMSInitiatingOccupancyFraction=75 \
     -XX:+UseCMSInitiatingOccupancyOnly \
     -XX:+PrintGCDetails \
     -XX:+PrintGCDateStamps \
     -Xloggc:/var/log/gc.log \
     -XX:PermSize=256m \
     -XX:MaxPermSize=512m \
     -jar myapp.jar


# Equivalent JDK 17 JVM arguments
java -Xms4g -Xmx4g \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=100 \
     -Xlog:gc*:file=/var/log/gc.log:time:filecount=5,filesize=20m \
     -XX:MaxMetaspaceSize=512m \
     --add-opens java.base/java.lang=ALL-UNNAMED \
     -jar myapp.jar</code></pre></div><h3><strong>8.2 JDK 17 &#8594; JDK 21 Migration</strong></h3><p>Compared with 8 &#8594; 17, this migration is much smoother. Main focus points:</p><ul><li><p>Virtual Threads adoption strategy: don&#8217;t roll it out everywhere at once. Pilot it on non-critical paths first, confirm there are no pinning issues, then scale.</p></li><li><p>Sequenced Collections: purely additive, no breaking changes.</p></li><li><p>Pattern Matching for switch: gradually replace if-else chains.</p></li></ul><pre><code><span># Migration example: enabling Virtual Threads in Spring Boot
# application.yml (Spring Boot 3.2+)
spring:
  threads:
    virtual:
      enabled: true
# This one line makes Tomcat handle requests with Virtual Threads</span></code></pre><p>JDK 21 GC migration advice:</p><pre><code><span># If you use G1 on JDK 17, you can keep it on JDK 21
# If you want to try Generational ZGC:
java -XX:+UseZGC -XX:+ZGenerational -Xms8g -Xmx8g -jar myapp.jar
# Note: ZGC needs more off-heap memory; we recommend sizing the container
# memory at 1.5-2x the heap</span></code></pre><h3><strong>8.3 Performance Benchmark Comparison</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!djLJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!djLJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 424w, https://substackcdn.com/image/fetch/$s_!djLJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 848w, https://substackcdn.com/image/fetch/$s_!djLJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 1272w, https://substackcdn.com/image/fetch/$s_!djLJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!djLJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png" width="1313" height="746" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:746,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!djLJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 424w, https://substackcdn.com/image/fetch/$s_!djLJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 848w, https://substackcdn.com/image/fetch/$s_!djLJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 1272w, https://substackcdn.com/image/fetch/$s_!djLJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3b36aac-2758-478b-b8c2-fc4d0ecd2875_1313x746.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Below are our measured results on identical hardware (8 cores, 16 G, Intel Xeon E5&#8211;2686 v4):</p><p>Throughput test (simulated e-commerce order API, 100 concurrent users for 5 minutes):</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nnyo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nnyo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 424w, https://substackcdn.com/image/fetch/$s_!nnyo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 848w, https://substackcdn.com/image/fetch/$s_!nnyo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 1272w, https://substackcdn.com/image/fetch/$s_!nnyo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nnyo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png" width="1313" height="304" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:304,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!nnyo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 424w, https://substackcdn.com/image/fetch/$s_!nnyo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 848w, https://substackcdn.com/image/fetch/$s_!nnyo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 1272w, https://substackcdn.com/image/fetch/$s_!nnyo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab63cd3-d3e9-4756-9656-0ae467a97687_1313x304.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>COH = Compact Object Headers</p><p>Data points worth noting:</p><ul><li><p>JDK 8 &#8594; JDK 17 (G1): QPS up ~23%, P99 down ~38%</p></li><li><p>JDK 17 &#8594; JDK 21 (G1): QPS up ~7%, long-tail latency clearly improved</p></li><li><p>ZGC&#8217;s P999 is 4x better than G1, but needs a larger heap</p></li><li><p>Compact Object Headers add ~5% throughput in scenarios with lots of small objects</p></li></ul><h2><strong>9. Version Selection Recommendations</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UtvS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UtvS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 424w, https://substackcdn.com/image/fetch/$s_!UtvS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 848w, https://substackcdn.com/image/fetch/$s_!UtvS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 1272w, https://substackcdn.com/image/fetch/$s_!UtvS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UtvS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png" width="1313" height="906" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:906,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UtvS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 424w, https://substackcdn.com/image/fetch/$s_!UtvS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 848w, https://substackcdn.com/image/fetch/$s_!UtvS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 1272w, https://substackcdn.com/image/fetch/$s_!UtvS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa11b931a-6b6d-44cc-a30a-dbc159417435_1313x906.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Decision matrix:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NB7J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NB7J!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 424w, https://substackcdn.com/image/fetch/$s_!NB7J!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 848w, https://substackcdn.com/image/fetch/$s_!NB7J!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 1272w, https://substackcdn.com/image/fetch/$s_!NB7J!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NB7J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png" width="1313" height="372" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:372,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NB7J!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 424w, https://substackcdn.com/image/fetch/$s_!NB7J!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 848w, https://substackcdn.com/image/fetch/$s_!NB7J!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 1272w, https://substackcdn.com/image/fetch/$s_!NB7J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb43e25b4-f914-4c5c-bb88-2dbad2aadf54_1313x372.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>My advice:</p><ul><li><p>If you&#8217;re still on JDK 8: it&#8217;s 2025 &#8212; upgrade as soon as possible. JDK 8&#8217;s public updates ended in 2019 (Oracle JDK), and security patches now depend on third-party distributions. Aim straight for JDK 21 or JDK 25, because the incremental migration cost from JDK 17 to JDK 21 is very low.</p></li><li><p>If you&#8217;re on JDK 17: JDK 21&#8217;s Virtual Threads is a reason to upgrade, especially for I/O-bound applications. JDK 25, as the newest LTS, is even better.</p></li><li><p>New projects: use JDK 25 directly.</p></li><li><p>Spring Boot compatibility quick reference:</p></li><li><p>Spring Boot 3.0&#8211;3.1: JDK 17 minimum, supports through JDK 20</p></li><li><p>Spring Boot 3.2&#8211;3.3: JDK 17 minimum, supports through JDK 22</p></li><li><p>Spring Boot 3.4+: JDK 17 minimum, supports through JDK 25</p></li></ul><h2><strong>References</strong></h2><ul><li><p>JDK 8 Features &#8212; Oracle</p></li><li><p>JDK 17 Release Notes &#8212; Oracle</p></li><li><p>JDK 21 JEP Index &#8212; OpenJDK</p></li><li><p>JDK 25 JEP Index &#8212; OpenJDK</p></li><li><p>JEP 444: Virtual Threads</p></li><li><p>JEP 439: Generational ZGC</p></li><li><p>JEP 519: Compact Object Headers</p></li><li><p>JEP 506: Scoped Values</p></li><li><p>JEP 513: Flexible Constructor Bodies</p></li><li><p>JEP 512: Compact Source Files and Instance Main Methods</p></li><li><p>JEP 511: Module Import Declarations</p></li><li><p>JEP 521: Generational Shenandoah</p></li><li><p>JEP 515: AOT Method Profiling</p></li><li><p>JEP 502: Stable Values (Preview)</p></li><li><p>JEP 485: Stream Gatherers</p></li><li><p>JEP 484: Class-File API</p></li><li><p>JEP 491: Synchronize Virtual Threads without Pinning</p></li><li><p>JEP 483: Ahead-of-Time Class Loading &amp; Linking</p></li><li><p>JEP 490: Remove Non-Generational ZGC</p></li><li><p>JEP 497: Quantum-Resistant ML-DSA</p></li><li><p>JEP 254: Compact Strings</p></li><li><p>JEP 310: Application Class-Data Sharing</p></li><li><p>JEP 350: Dynamic CDS Archives</p></li><li><p>Project Loom &#8212; OpenJDK</p></li><li><p>Project Panama &#8212; OpenJDK</p></li><li><p>Project Leyden &#8212; OpenJDK</p></li><li><p>Project Valhalla &#8212; OpenJDK</p></li><li><p>Project Lilliput &#8212; OpenJDK</p></li><li><p>Spring Boot System Requirements</p></li><li><p>OpenRewrite Spring Boot 3 Migration</p></li></ul>]]></content:encoded></item><item><title><![CDATA[No More "if (object == null)" in Our Java Project, and I Got Rewarded by My Boss]]></title><description><![CDATA[&#128512;]]></description><link>https://seabreeze0828.substack.com/p/no-more-if-object-null-in-our-java</link><guid isPermaLink="false">https://seabreeze0828.substack.com/p/no-more-if-object-null-in-our-java</guid><dc:creator><![CDATA[Dylan Smith]]></dc:creator><pubDate>Sat, 01 Aug 2026 09:17:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DDcC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DDcC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DDcC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 424w, https://substackcdn.com/image/fetch/$s_!DDcC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 848w, https://substackcdn.com/image/fetch/$s_!DDcC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 1272w, https://substackcdn.com/image/fetch/$s_!DDcC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DDcC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png" width="1408" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1408,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2252974,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://seabreeze0828.substack.com/i/209357276?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DDcC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 424w, https://substackcdn.com/image/fetch/$s_!DDcC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 848w, https://substackcdn.com/image/fetch/$s_!DDcC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 1272w, https://substackcdn.com/image/fetch/$s_!DDcC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30557cf-cc16-489c-a34d-de1077911b7b_1408x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Recently, a friend of mine joined a new company. Since there was a lot of code in the project that directly judged whether an object is null. So my friend optimized it by using Optional and was praised by the boss.</p><p>Now let&#8217;s introduce it in detail.</p><p>In the previous article we have introduced <a href="https://seabreeze0828.substack.com/p/java-the-clearest-lambda-explanation">Lambda expression in java</a>. In this article, I will introduce how to combine Lambda expression and Optional make Java handle null more gracefully.</p><p>Suppose we have a student object&#65292;and an Optional wrapper for the student object:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;9b6fa7bd-1e0b-4cf9-a2c2-72b0d5826f3a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class OptionalTest {
&#8203;
    public static void main(String[] args) {
        Student student = new Student(&#8221;Bob&#8221;, 18);
        Optional&lt;Student&gt; studentOpt = Optional.ofNullable(student);
    }
&#8203;
    @Getter
    @AllArgsConstructor
    public static class Student {
        private String name;
        private Integer age;
    }
}</code></pre></div><p>Optional cannot make the original cumbersome null check simpler if it is not used in conjunction with Lambda&#65292;such as</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;4efb5084-0631-49d8-b52a-9061b2900622&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">//writing method 1if (student == null) {
  return UNKNOWN_STUDENT;
} else {
  return student;
}
&#8203;
//writing method 2 is just as bad as writing method 1
if (!studentOpt.isPresent()) {
  return UNKNOWN_STUDENT;
} else {
  return studentOpt.get();
}</code></pre></div><p>Only when Optional is used in combination with Lambda can its true power be exerted!</p><p>Let&#8217;s now compare the following four common null handling differences between Java8&#8217;s Lambda + Optional and traditional Java.</p><p><strong>Situation 1 &#8212; Start if it exists</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;eb5983dd-8124-4028-8a49-e809e3b9eff4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// if
if (student != null) {
  System.out.println(student);
}
&#8203;
// Optinal
studentOpt.ifPresent(System.out::println);</code></pre></div><p><strong>Case 2 &#8212; Return if it exists, <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">if not return fart</mark> or throw exception</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;99c6d338-4e43-4bb1-bb77-f1e9c65752d9&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// if
if (student == null) {
  return UNKNOWN_STUDENT;   // or throw exception
} else {
  return student;
}
&#8203;
// Optinal
return studentOpt.orElse(UNKNOWN_STUDENT);
return studentOpt.orElseThrow(RuntimeException::new);</code></pre></div><p><strong>Case 3 &#8212; If it exists, it is returned. If not, it is <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">generated</mark> by the function</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;9b33e7fe-cb2f-477a-bce8-2f95dfd880e7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// if
if (student == null) {
  return UNKNOWN_STUDENT;
} else {
  return generateWithFunction();
}
&#8203;
// Optinal
return studentOpt.orElseGet(() -&gt; generateWithFunction());</code></pre></div><p><strong>Case 4 &#8212; Continuous null checks</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;e6371d14-4efa-4d10-a740-bf52b8ed2b05&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class OptionalCase {


    public static void main(String[] args) {
        Student student = new Student(&#8221;Bob&#8221;, 18,
                new Street(&#8221;Main Street&#8221;, new City(&#8221;Los Angeles&#8221;, new State(&#8221;CA&#8221;))));

        System.out.println(getStateFromJava7(student));
        System.out.println(getStateFromJava8(student));
    }

    private static String getStateFromJava7(Student student) {
        // Java 7
        if (student != null) {
            Street street = student.getAddress();
            if (street != null) {
                City city = street.getCity();
                if (city != null) {
                    State state = city.getState();
                    if (state != null) {
                        String stateName = state.getName();
                        if (stateName != null) {
                            return stateName;
                        }
                        return &#8220;unknown&#8221;;
                    }
                    return &#8220;unknown&#8221;;
                }
                return &#8220;unknown&#8221;;
            }
            return &#8220;unknown&#8221;;
        }
        return &#8220;unknown&#8221;;
    }

    private static String getStateFromJava8(Student student) {
        Optional&lt;Student&gt; studentOpt = Optional.ofNullable(student);
        // Java 8
        return studentOpt
                .map(Student::getAddress)
                .map(Street::getCity)
                .map(City::getState)
                .map(State::getName)
                .orElse(&#8221;unknown&#8221;);
    }

    @Getter
    @AllArgsConstructor
    static class Student {
        private String name;
        private Integer age;
        private Street address;
    }

    @Getter
    @AllArgsConstructor
    static class Street {
        private String name;
        private City city;
    }

    @Getter
    @AllArgsConstructor
    static class City {
        private String name;
        private State state;
    }

    @Getter
    @AllArgsConstructor
    static class State {
        private String name;
    }
}</code></pre></div><p>It can be clearly seen from the above four situations that Optional + Lambda allows us to write a lot less if-Else blocks. Especially for situation 4, the traditional Java writing method seems lengthy and difficult to understand, while <strong>Optional+Lambda</strong> is refreshing, clear and concise.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview</span></a></p><p><em><strong>If this post has helped you out in any way, I&#8217;d truly appreciate you becoming a paid subscriber. Your ongoing support keeps me motivated to keep crafting more thorough, high-quality technical content down the line. Thank you so much.</strong></em></p>]]></content:encoded></item><item><title><![CDATA[Deep Dive Into Java Stream Collect: A Comprehensive Full Explanation]]></title><description><![CDATA[As titled]]></description><link>https://seabreeze0828.substack.com/p/deep-dive-into-java-stream-collect</link><guid isPermaLink="false">https://seabreeze0828.substack.com/p/deep-dive-into-java-stream-collect</guid><dc:creator><![CDATA[Dylan Smith]]></dc:creator><pubDate>Sat, 01 Aug 2026 09:00:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4q1K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4q1K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4q1K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 424w, https://substackcdn.com/image/fetch/$s_!4q1K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 848w, https://substackcdn.com/image/fetch/$s_!4q1K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 1272w, https://substackcdn.com/image/fetch/$s_!4q1K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4q1K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png" width="864" height="486" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c60b00a7-479f-4a9b-9077-e832e670607e_864x486.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:486,&quot;width&quot;:864,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Stream Collect&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Stream Collect" title="Stream Collect" srcset="https://substackcdn.com/image/fetch/$s_!4q1K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 424w, https://substackcdn.com/image/fetch/$s_!4q1K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 848w, https://substackcdn.com/image/fetch/$s_!4q1K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 1272w, https://substackcdn.com/image/fetch/$s_!4q1K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60b00a7-479f-4a9b-9077-e832e670607e_864x486.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>In the previous article&#65292;<strong><a href="https://seabreeze0828.substack.com/p/one-article-to-master-java-streams">Mastering Java Stream in One Article</a></strong>, we have explained the overall situation of Stream in detail, and also roughly introduced the common usage of the collect method, but this is just the tip of the iceberg.</p><p>This article will specifically analyze the collect operation and unlock more advanced usage, making the Stream operation truly a magic weapon in our coding.</p><p>Let&#8217;s start from an example and expand the definition of Student class.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;aa469ed6-9f1d-4290-9165-0ecbdee9e968&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Getter
@AllArgsConstructor
public static class Student {
    private String department;
    private String name;
    private Integer age;
    private String sex;
  
    @Override
    public String toString() {
      return &#8220;Student{name=&#8217;&#8221; + name + &#8220;&#8217;, department=&#8221; + department + &#8220;&#8217;, age=&#8221; + age + &#8220;&#8217;, sex=&#8221; + sex + &#8220;}&#8221;;
    }
}</code></pre></div><p>We now have a group of students with the following information:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a603e1ef-d24c-4ec8-8ca7-50a0ebc09822&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">List&lt;Student&gt; allStudents = Lists.newArrayList(
      new Student(&#8221;Computer&#8221;, &#8220;Bob&#8221;, 18, &#8220;male&#8221;),
      new Student(&#8221;Computer&#8221;, &#8220;Ted&#8221;, 17, &#8220;male&#8221;),
      new Student(&#8221;Economics&#8221;, &#8220;Zeka&#8221;, 19, &#8220;male&#8221;),
      new Student(&#8221;Economics&#8221;, &#8220;Alan&#8221;, 19, &#8220;male&#8221;),
      new Student( &#8220;Computer&#8221;, &#8220;Anne&#8221;, 21, &#8220;female&#8221;),
      new Student(&#8221;Physics&#8221;, &#8220;Davis&#8221;, 21, &#8220;female&#8221;)
);</code></pre></div><p>You need to implement such a requirement:</p><blockquote><p><em>In the given list of students, filter out all the students in the computer department.</em></p></blockquote><p>If you have ever used Stream, or if you have read my <a href="https://medium.com/stackademic/mastering-java-stream-in-one-article-10196b449809">previous article on Stream</a>, then the above claims can be easily achieved with the help of Stream:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;7fa9176b-8b47-4b05-bdc2-7f44d8a2e738&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public void filterComputerDepartmentStudents(List&lt;Student&gt; students) {
        List&lt;Student&gt; computerStudents = students.stream()
                .filter(s -&gt; Objects.equals(s.getDepartment(), &#8220;Computer&#8221;))
                .collect(Collectors.toList());
        System.out.println(computerStudents);
    }</code></pre></div><p>Easy peasy! But don&#8217;t get too happy, the actual needs are often not so simple, for example, the demand now becomes this</p><blockquote><p><em>In the given list of students, filter out all computer science students and group them by gender</em></p></blockquote><p>In fact, it just adds a new grouping requirement, a small change! It only needs to be processed in two steps. First, follow the logic of the previous code and then group the results:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;5d52c23c-cb90-49fc-b1c0-384f06564a98&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public void filterComputerStudentsGroupBySex(List&lt;Student&gt; students) {
    // step1, filter
    List&lt;Student&gt; computerStudents = students.stream()
            .filter(s -&gt; Objects.equals(s.getDepartment(), &#8220;Computer&#8221;))
            .collect(Collectors.toList());
&#8203;
    // step2, group
    Map&lt;String, List&lt;Student&gt;&gt; resultMap = new HashMap&lt;&gt;();
    for (Student student : computerStudents) {
        List&lt;Student&gt; groupList = resultMap.computeIfAbsent(student.getDepartment(), s -&gt; new ArrayList&lt;&gt;());
        groupList.add(student);
    }
}</code></pre></div><p>It does not seem to be a problem, and I believe that many of my friends are actually coding in the same way. But in fact, we can also use the Stream operation is done directly:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;05fc8219-6a55-4e0c-875b-4f59132b71e8&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public void filterComputerGroupByStream(List&lt;Student&gt; students) {
        Map&lt;String, List&lt;Student&gt;&gt; resultMap = students.stream()
                .filter(s -&gt; Objects.equals(s.getDepartment(), &#8220;Computer&#8221;))
                .collect(Collectors.groupingBy(Student::getSex));
        System.out.println(resultMap);
    }</code></pre></div><p>Isn&#8217;t that cool? One line of code does it all! Doesn&#8217;t writing code like this feel like writing a requirements document that describes what I want, not how to do it?</p><p>Both of the above would result in the following.</p><pre><code><span>{
  female=[Student{name=&#8217;Anne&#8217;, department=&#8217;Computer&#8217;, age=21&#8217;, sex=&#8217;female&#8217;}], 
  male=[Student{name=&#8217;Bob&#8217;, department=&#8217;Computer&#8217;, age=18&#8217;, sex=&#8217;male&#8217;}, Student{name=&#8217;Ted&#8217;, department=&#8217;Computer&#8217;, age=17&#8217;, sex=&#8217;male&#8217;}]
}</span></code></pre><p>Let&#8217;s take a closer look at collect and unlock more ways to use it.</p><h2><strong>Introduction to collect</strong></h2><p>I believe that when you first come into contact with Stream collect, you will suddenly see the concepts of collect, Collector, and Collectors. It is easy for you to confuse them. Let&#8217;s take a look at their differences and connections respectively;</p><ol><li><p><code>collect</code>: This is one of the <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">termination</mark> methods of Stream. The accepted parameter is a specific implementation class of the Collector interface, and the collector is used to perform related operations on the data entering the collect;</p></li><li><p><code>Collector</code>&#65306;It is an <strong>interface</strong>, which is the input parameter of the collect method;</p></li><li><p><code>Collectors</code>&#65306;It is a tool class that provides many specific implementation classes of the Collector interface, which are some more general collectors preset for convenience of use (of course, you can implement the Collector interface yourself without using the implementation provided by the Collectors class).</p></li></ol><p>Let&#8217;s take the simplest usage scenario of <code>collect</code> and look at the relationship between the three to deepen our understanding. As shown in the figure below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mV4t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mV4t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 424w, https://substackcdn.com/image/fetch/$s_!mV4t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 848w, https://substackcdn.com/image/fetch/$s_!mV4t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 1272w, https://substackcdn.com/image/fetch/$s_!mV4t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mV4t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png" width="1155" height="579" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:579,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mV4t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 424w, https://substackcdn.com/image/fetch/$s_!mV4t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 848w, https://substackcdn.com/image/fetch/$s_!mV4t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 1272w, https://substackcdn.com/image/fetch/$s_!mV4t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c55309d-fbc5-454e-ae2a-b78bc02a5a2e_1155x579.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Use of Collector</strong></h2><p>In fact, it can be seen that Collector is the most important concept of them all, which controls what kind of processing logic is to be carried out and can be categorized into the following three groups:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QzmL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QzmL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 424w, https://substackcdn.com/image/fetch/$s_!QzmL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 848w, https://substackcdn.com/image/fetch/$s_!QzmL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 1272w, https://substackcdn.com/image/fetch/$s_!QzmL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QzmL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png" width="1138" height="436" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:436,&quot;width&quot;:1138,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!QzmL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 424w, https://substackcdn.com/image/fetch/$s_!QzmL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 848w, https://substackcdn.com/image/fetch/$s_!QzmL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 1272w, https://substackcdn.com/image/fetch/$s_!QzmL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a4bc6b0-059c-46e0-9841-f3419408ba88_1138x436.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>1.Collection type</strong></h3><p>This is the most commonly used type. After a series of intermediate operations, the remaining elements are taken out of the Stream and placed directly into the collection object.</p><p>The <code>Collectors</code> tool class preset provides three methods that return collection types, as follows:</p><h3><strong>2.Single result type</strong></h3><p>For the operation of a single result type, the elements in the Stream are traversed one by one, into the Collector processing function, and then it will be merged with the processing result of the previous element to process and get a new result, and so on, until the output of the final result.</p><p>For example, the processing logic of Collectors.maxBy() is shown below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!39LN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!39LN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 424w, https://substackcdn.com/image/fetch/$s_!39LN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 848w, https://substackcdn.com/image/fetch/$s_!39LN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 1272w, https://substackcdn.com/image/fetch/$s_!39LN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!39LN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png" width="1155" height="300" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/addf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:300,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!39LN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 424w, https://substackcdn.com/image/fetch/$s_!39LN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 848w, https://substackcdn.com/image/fetch/$s_!39LN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 1272w, https://substackcdn.com/image/fetch/$s_!39LN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf3d53-c4c1-4324-87a8-47907297ebfd_1155x300.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The execution logic of methods such as <code>minBy()</code>, <code>summingInt()</code>, etc. is much the same as theirs, essentially processing them one by one to produce a final result.</p><p>Let&#8217;s recall the example mentioned in the <a href="https://blog.stackademic.com/mastering-java-stream-in-one-article-10196b449809">previous article</a> to find the maximum age of the football team students. Now we can achieve it like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;1723ff74-8ef7-441e-afdc-1a6623d64e44&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">List&lt;Student&gt; footballStudent = Lists.newArrayList(
                new Student(&#8221;Alan&#8221;, 19),
                new Student(&#8221;Anne&#8221;, 21),
                new Student(&#8221;Davis&#8221;, 21));
&#8203;
//Collectors.maxBy()
footballStudent.stream()
                .map(Student::getAge)
                .collect(Collectors.maxBy(Comparator.comparingInt(a -&gt; a)))
                .ifPresent(a -&gt; System.out.println(&#8221;The maximum age for a football team is &#8220; + a));
&#8203;</code></pre></div><p>However, in fact, this method is not recommended. For the convenience of use, JDK provides a simplified encapsulation of the above logic. We can directly use the <code>max()</code> method to implement it, that is, the above code is equivalent to the following writing:</p><pre><code><span>footballStudent.stream()
    .map(Student::getAge)
    .max(Comparator.comparing(a -&gt; a))
    .ifPresent(a -&gt; System.out.println(&#8221;The maximum age for a football team is &#8220; + a));</span></code></pre><p>In fact, your <strong>idea</strong> will also give prompts for inappropriate code, and a wavy line will appear under this part of the code.</p><p>You can optimize with one click through option + enter &#128513;.</p><h3><strong>3.Grouping type</strong></h3><p>Grouping operation is an extremely important usage scenario of collect. The <strong>Collectors tool class</strong> provides the <code>groupingBy()</code> method to obtain a grouping operation Collector. The <code>groupingBy()</code> operation requires specifying two key inputs, namely <strong>Classification Function</strong> and <strong>Value Collector</strong>:</p><ul><li><p><strong>Classification function </strong>: used for processing based on the specified elements, return a value for grouping (i.e., the <code>Key</code> of the grouping result Map), for the function after processing the return value of the same elements, will be assigned to the same group.</p></li><li><p><strong>Value Collector</strong>: For further processing logic of grouped data elements, this is still a regular Collector, which is exactly the same as the collector passed in the <code>collect()</code> method (as can be seen, There can be nested logic here, which will be introduced in detail later).</p></li></ul><p>For ease of use, two overloaded implementations of <code>groupingBy</code> are provided in the Collectors tool class. One of the methods only needs to pass in a classification function. This is because it uses <code>toList()</code> as the value collector by default, as follows:</p><p>When it is just a basic grouping, just pass in a classification function, just like the example at the beginning of the article, here is the code:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;ddbeb573-1a1c-44c3-be57-3455da5a1803&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public void filterComputerGroupByStream(List&lt;Student&gt; students) {
        Map&lt;String, List&lt;Student&gt;&gt; resultMap = students.stream()
                .filter(s -&gt; Objects.equals(s.getDepartment(), &#8220;Computer&#8221;))
                .collect(Collectors.groupingBy(Student::getSex));
        System.out.println(resultMap);
    }</code></pre></div><p>Let&#8217;s take this code as an example and look at its execution logic diagram:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vx_J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vx_J!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 424w, https://substackcdn.com/image/fetch/$s_!Vx_J!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 848w, https://substackcdn.com/image/fetch/$s_!Vx_J!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 1272w, https://substackcdn.com/image/fetch/$s_!Vx_J!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vx_J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png" width="1155" height="291" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:291,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Vx_J!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 424w, https://substackcdn.com/image/fetch/$s_!Vx_J!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 848w, https://substackcdn.com/image/fetch/$s_!Vx_J!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 1272w, https://substackcdn.com/image/fetch/$s_!Vx_J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5082e33c-5b0b-4859-b805-48c265e245cb_1155x291.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When you not only need to group, but also need to perform some additional processing on the grouped data, you need to provide both a classification function and a value collector:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;64336c59-6640-496e-9e6a-e06311e5a822&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public static void filterComputerGroupByStream(List&lt;Student&gt; students) {
        Map&lt;String, Long&gt; resultMap = students.stream()
                .filter(s -&gt; Objects.equals(s.getDepartment(), &#8220;Computer&#8221;))
                .collect(Collectors.groupingBy(Student::getSex, Collectors.counting()));
        System.out.println(resultMap);
    }</code></pre></div><p>Output:</p><pre><code><span>{female=1, male=2}</span></code></pre><p>In the above code, <code>Collectors.groupingBy()</code> is a grouping Collector, and a <code>Collectors.counting()</code> is passed in. It also returns a Collector, which means that one Collector is nested in another. Collector.</p><h3><strong>Advanced usage of overlays</strong></h3><p>Let&#8217;s look at a more complex scenario. The previous request was to filter out students from the computer department and then group them according to gender.</p><p>Now the requirement is not limited to the computer department. It is required to first group the students by department, then group them by gender, and return all corresponding numbers.</p><p>At first glance, of course we cannot process each department separately. With the help of the collect operation, we can achieve this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a037c375-3390-4cce-b3de-5742364736b3&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public static void groupByDepartmentAndSex(List&lt;Student&gt; students) {
        Map&lt;String, Map&lt;String, Long&gt;&gt; resultMap = students.stream()
                .collect(Collectors.groupingBy(Student::getDepartment,
                        Collectors.groupingBy(Student::getSex,
                                Collectors.counting())));
        System.out.println(resultMap);
    }</code></pre></div><p>Output:</p><pre><code><span>{
  Economics={male=2}, 
  Computer={female=1, male=2}, 
  Physics={female=1}
}</span></code></pre><p>If you wish, you can continue to nest to complete more complex requirements.</p><h3><strong>Use of partitioningBy</strong></h3><p>For the requirement of grouping according to gender, since gender has only two values, it can actually be considered as a bool value, that is, the grouping key is of bool type. In this case, we can also achieve this requirement through the <code>Collectors.partitioningBy()</code> method, as follows:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;30f32e35-3408-4fb1-82ce-96d43782f7a7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public static void partitioningBySex(List&lt;Student&gt; students) {
        Map&lt;String, Map&lt;Boolean, Long&gt;&gt; resultMap = students.stream()
                .collect(Collectors.groupingBy(Student::getDepartment,
                        Collectors.partitioningBy(s -&gt; Objects.equals(s.getSex(), &#8220;male&#8221;),
                                Collectors.counting())));
        System.out.println(resultMap);
    }</code></pre></div><p>true means male, false means female,</p><p>Output:</p><pre><code><span>{
  Economics={false=0, true=2}, 
  Computer={false=1, true=2}, 
  Physics={false=1, true=0}
}</span></code></pre><p>From a purely usage perspective, the return value of the <code>classification function</code> of the grouping collector is <code>Boolean</code>, so the effects of <code>Collectors.partitioningBy()</code> and <code>Collectors.groupingBy()</code> are basically the same.</p><h3><strong>Use of collectAndThen</strong></h3><p>The collector corresponding to <code>collectAndThen</code>, in addition to passing in a downstream that is actually used for result collection and processing, also needs to pass in a finisher method. After <code>downstream</code> calculates the result, the <code>finisher</code> method is used to perform secondary processing on the result. Process and return the processing results as final data.</p><p>Let&#8217;s look at an example like this</p><blockquote><p><em>After grouping according to departments, then grouping according to gender, taking the age of the oldest student in each group.</em></p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;e39b634c-ec2f-48bf-a4ef-feffa9a441ea&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public static void getOldestStudentGroup(List&lt;Student&gt; students) {
        Map&lt;String, Map&lt;Boolean, Optional&lt;Student&gt;&gt;&gt; resultMap = students.stream()
                .collect(Collectors.groupingBy(Student::getDepartment,
                        Collectors.partitioningBy(s -&gt; Objects.equals(s.getSex(), &#8220;male&#8221;),
                                Collectors.maxBy(Comparator.comparing(Student::getAge)))));
        System.out.println(&#8221;The oldest male student in the Computer Department is: &#8220;
                + resultMap.get(&#8221;Computer&#8221;).get(true).map(Student::getAge).orElse(0));
    }</code></pre></div><p>Output:</p><pre><code><span>The oldest male student in the Computer Department is: 18</span></code></pre><p>It is worth noting that the object returned after processing by <code>maxBy()</code> here is wrapped by <code>Optional</code>. In order to get the final value, we need to perform some additional operations.</p><p>In most cases, we expect to get the final value directly instead of the <code>Optional</code> object. In this case, we can use <code>collectAndThen</code> to get the purpose.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;c4207f11-2d1a-4a52-8b5f-b4e263e4937f&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public static void collectAndThen(List&lt;Student&gt; students) {
        Map&lt;String, Map&lt;Boolean, Integer&gt;&gt; resultMap = students.stream()
                .collect(Collectors.groupingBy(Student::getDepartment,
                        Collectors.partitioningBy(s -&gt; Objects.equals(s.getSex(), &#8220;male&#8221;),
                                Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Student::getAge)),
                                        a -&gt; a.map(Student::getAge).orElse(0)))));
        System.out.println(resultMap);
        System.out.println(&#8221;The oldest male student in the Computer Department is: &#8220; + resultMap.get(&#8221;Computer&#8221;).get(true));
    }</code></pre></div><p>Output:</p><pre><code><span>{
  Economics={false=0, true=19}, 
  Computer={false=21, true=18}, 
  Physics={false=21, true=0}
}
The oldest male student in the Computer Department is: 18</span></code></pre><p>How does it feel to get it right in one step? Isn&#8217;t it very comfortable?&#128516;</p><h2><strong>Custom collector</strong></h2><p>Although the Collectors tool class provides many commonly used collectors, perhaps in the project, we will encounter some scenarios that require customization, and the existing collectors cannot meet our needs. At this time, we can also implement the Collector ourselves. The interface meets the requirements.</p><h3><strong>Collector interface detailed explanation</strong></h3><p>If you want to customize your own <code>Collector</code>, you must first understand what methods the <code>Collector</code> interface has that we need to implement, as well as the functions and uses of each method.</p><p>When we create a new <code>CustomCollector</code> class and declare to implement the Collector interface, we will find that we need to implement 5 methods:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c9Ax!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c9Ax!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 424w, https://substackcdn.com/image/fetch/$s_!c9Ax!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 848w, https://substackcdn.com/image/fetch/$s_!c9Ax!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 1272w, https://substackcdn.com/image/fetch/$s_!c9Ax!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c9Ax!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png" width="1138" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1138,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!c9Ax!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 424w, https://substackcdn.com/image/fetch/$s_!c9Ax!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 848w, https://substackcdn.com/image/fetch/$s_!c9Ax!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 1272w, https://substackcdn.com/image/fetch/$s_!c9Ax!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbff6efb-1db5-4a75-886b-88bf7a2d9946_1138x480.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The meanings of these five interfaces are summarized as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gMLd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gMLd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 424w, https://substackcdn.com/image/fetch/$s_!gMLd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 848w, https://substackcdn.com/image/fetch/$s_!gMLd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 1272w, https://substackcdn.com/image/fetch/$s_!gMLd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gMLd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png" width="1155" height="426" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:426,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!gMLd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 424w, https://substackcdn.com/image/fetch/$s_!gMLd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 848w, https://substackcdn.com/image/fetch/$s_!gMLd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 1272w, https://substackcdn.com/image/fetch/$s_!gMLd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e9c9e0a-755c-4785-a835-a7280e3d01a7_1155x426.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Regarding the optional values of Characteristics, please see the interface description, as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jr72!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jr72!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 424w, https://substackcdn.com/image/fetch/$s_!Jr72!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 848w, https://substackcdn.com/image/fetch/$s_!Jr72!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 1272w, https://substackcdn.com/image/fetch/$s_!Jr72!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jr72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png" width="1155" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Jr72!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 424w, https://substackcdn.com/image/fetch/$s_!Jr72!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 848w, https://substackcdn.com/image/fetch/$s_!Jr72!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 1272w, https://substackcdn.com/image/fetch/$s_!Jr72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b95b70c-73bc-4409-81ff-7b5696948fd0_1155x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Now that we know the meanings and uses of these five interfaces, how do these interfaces work together? We can take a look at the implementation source code of the collector <code>Collectors.toList()</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;32bfab7d-1ab6-4da4-b28f-100e0f34fcfc&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public final class Collectors {
&#8203;
    static final Set&lt;Collector.Characteristics&gt; CH_ID
            = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
&#8203;
public static &lt;T&gt;
    Collector&lt;T, ?, List&lt;T&gt;&gt; toList() {
        return new CollectorImpl&lt;&gt;((Supplier&lt;List&lt;T&gt;&gt;) ArrayList::new, List::add,
                                   (left, right) -&gt; { left.addAll(right); return left; },
                                   CH_ID);
    }
}</code></pre></div><p>The CollectorImpl returned by the <code>toList()</code> method implements Collector and receives four parameters here. Let&#8217;s take a look at them in turn:</p><ul><li><p><strong>supplier</strong>&#65306;<code>ArrayList::new</code>,that is, an <code>ArrayList</code> is created as the result storage container&#12290;</p></li><li><p><strong>accumulator</strong>&#65306;<code>List::add</code>, that is, for each element in the stream, the <code>list.add()</code> method is called to add it to the result container.</p></li><li><p><strong>combiner</strong>&#65306;<code>(left, right) -&gt; { left.addAll(right); return left; }</code>&#65292;the various sub-<code>ArrayList</code> results generated by parallel operations are merged into the final result through the <code>list.addAll()</code> method.</p></li><li><p><strong>characteristics</strong>: You can see that <code>CH_ID</code> is used, which only contains Characteristics.IDENTITY_FINISH, that is, the final result is returned directly without secondary processing by the finisher method. Note that <code>CONCURRENT</code> is not declared here, because ArrayList is a non-thread-safe container, <strong>so this collector does not support use in concurrent processes.</strong></p></li></ul><p>In fact, CollectorImpl has two constructors. The constructor that accepts four parameters above will still call the constructor that receives five parameters, that is, it also needs to pass in <code>finisher</code>, but there is no need to process the result twice, so <code>castingIdentity()</code> is passed in by default, which returns itself.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mKtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mKtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 424w, https://substackcdn.com/image/fetch/$s_!mKtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 848w, https://substackcdn.com/image/fetch/$s_!mKtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 1272w, https://substackcdn.com/image/fetch/$s_!mKtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mKtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png" width="1064" height="224" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:224,&quot;width&quot;:1064,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mKtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 424w, https://substackcdn.com/image/fetch/$s_!mKtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 848w, https://substackcdn.com/image/fetch/$s_!mKtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 1272w, https://substackcdn.com/image/fetch/$s_!mKtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56953168-8c97-4ceb-b13a-68bec3a7a271_1064x224.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">Finally</mark>, we use a picture to illustrate the process of processing data with several methods:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!udBx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!udBx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 424w, https://substackcdn.com/image/fetch/$s_!udBx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 848w, https://substackcdn.com/image/fetch/$s_!udBx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 1272w, https://substackcdn.com/image/fetch/$s_!udBx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!udBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png" width="1155" height="276" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:276,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!udBx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 424w, https://substackcdn.com/image/fetch/$s_!udBx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 848w, https://substackcdn.com/image/fetch/$s_!udBx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 1272w, https://substackcdn.com/image/fetch/$s_!udBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f3a84b6-e0b5-4349-8909-405e9f981d1d_1155x276.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Of course, if our Collector supports use in parallel streams, the processing process will be slightly different:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hn-2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hn-2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 424w, https://substackcdn.com/image/fetch/$s_!hn-2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 848w, https://substackcdn.com/image/fetch/$s_!hn-2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 1272w, https://substackcdn.com/image/fetch/$s_!hn-2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hn-2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png" width="1155" height="289" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:289,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!hn-2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 424w, https://substackcdn.com/image/fetch/$s_!hn-2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 848w, https://substackcdn.com/image/fetch/$s_!hn-2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 1272w, https://substackcdn.com/image/fetch/$s_!hn-2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2e8f656-a097-4d70-968c-1e80c9e93bf8_1155x289.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>CustomCollector specific implementation</strong></h3><p>We have already understood the main methods in the <code>Collector</code> interface, now let us start implementing our own Collector!</p><p>Now suppose we have such a statistical requirement:</p><blockquote><p><em>Calculate the student&#8217;s performance level. When the student&#8217;s score is greater than or equal to 90 points, 3 points will be scored. If the student score is greater than or equal to 80 points, 2 points will be scored. If the student score is greater than or equal to 60 points, 1 point will be scored. Otherwise, 0 points will be scored.</em></p></blockquote><p>Next, let&#8217;s customize a collector to implement this function.</p><p><strong>1.supplier</strong></p><p>The purpose of the supplier method is to create a container where the results are stored and accumulated. Since we want to calculate the statistical results of multiple values, we must first declare an <code>int result = 0</code> to store the accumulated results. However, in order for our Collector to support use in concurrent mode, we can use thread-safe AtomicInteger to implement it.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;54e56f54-90b7-43da-98b3-1eb375d3c7b4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Override
public Supplier&lt;AtomicInteger&gt; supplier() {
    // Responsible for the gradual collection of the final result,
    // here return new AtomicInteger(0), subsequent accumulation on the basis of this
    return () -&gt; new AtomicInteger(0);
}</code></pre></div><p><strong>2.accumulator</strong></p><p>The <code>accumulator</code> method implements specific calculation logic and is also the core method in the entire Collector. The <code>accumulator</code> method will process the elements entering the Collector one by one:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a03e4d04-0143-4f3f-a7d5-b370082650c9&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Override
public BiConsumer&lt;AtomicInteger, Student&gt; accumulator() {
    // The processing strategy after each element enters
    return (result, current) -&gt; {
        int intValue = mapper.applyAsInt(current);
        if (intValue &gt;= 90) {
            result.addAndGet(3);
        } else if (intValue &gt;= 80) {
            result.addAndGet(2);
        } else if (intValue &gt;= 60) {
            result.addAndGet(1);
        }
    };
}</code></pre></div><p>Here is a supplementary explanation. Among the several methods of Collector, only <code>accumulator</code> needs to be executed repeatedly. It will be executed as many times as there are elements. The other methods will not directly deal with the elements in the Stream.</p><p><strong>3.combiner</strong></p><p>Because the thread-safe AtomicInteger is used as the result container in the previous supplier method, it supports use in parallel streams. According to the above introduction, parallel streaming is to divide the Stream into multiple fragments, and then calculate and process the fragments separately to obtain the results of each fragment. <strong>Finally, the results of these fragments need to be merged into the same total result</strong>. How to merge this , which is what we need to implement here:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;c2488e8d-e7d1-46ea-be68-650c790e3302&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Override
public BinaryOperator&lt;AtomicInteger&gt; combiner() {
    // Handling of multiple segmented results, direct summation
    return (result1, result2) -&gt; {
        result1.addAndGet(result2.get());
        return result1;
    };
}</code></pre></div><p><strong>4.finisher</strong></p><p>The target result of our Collector is to output an accumulated <code>Integer</code> value, but in order to ensure thread safety in concurrent streams, we use AtomicInteger as the result container. That is to say, in the end we need to convert the internal <code>AtomicInteger</code> object into an Integer object, so our implementation logic of the <code>finisher</code> method is as follows:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;4e0475cb-9463-42de-9de0-a8ea8496a1a4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Override
public Function&lt;AtomicInteger, Integer&gt; finisher() {
    return AtomicInteger::get;
}</code></pre></div><p><strong>5.characteristics</strong></p><p>Look at what features we need for our Collector:</p><ul><li><p>Because we are implementing a Collector that allows for use in parallel streams, the <code>CONCURRENT</code> property needs to be declared;</p></li><li><p>As a statistical operation, there is no requirement for the order of calculation of elements, so we also declare the <code>UNORDERED</code> attribute at the same time;</p></li><li><p>Because our finisher method is doing a result processing transformation operation, not returning itself, the <code>IDENTITY_FINISH</code> attribute cannot be declared here.</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;34954365-e64e-4f1f-94ce-82230f952bcc&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Override
public Set&lt;Characteristics&gt; characteristics() {
    Set&lt;Characteristics&gt; characteristics = new HashSet&lt;&gt;();
    characteristics.add(Characteristics.CONCURRENT);
    characteristics.add(Characteristics.UNORDERED);
    // characteristics.add(Characteristics.IDENTITY_FINISH);
    return characteristics;
}</code></pre></div><p>Finally, we use our custom Collector for testing. Before that, we need to add an Integer type attribute <code>score</code> to the previous <code>Student</code> class and initialize a batch of students.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;f871abd9-ee0f-4202-8a3f-1963c50fa232&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public static void main(String[] args) {
    List&lt;Student&gt; allStudents = Lists.newArrayList(
            new Student(&#8221;Computer&#8221;, &#8220;Bob&#8221;, 18, &#8220;male&#8221;, 59),
            new Student(&#8221;Computer&#8221;, &#8220;Ted&#8221;, 17, &#8220;male&#8221;, 60),
            new Student(&#8221;Economics&#8221;, &#8220;Zeka&#8221;, 19, &#8220;male&#8221;, 70),
            new Student(&#8221;Economics&#8221;, &#8220;Alan&#8221;, 19, &#8220;male&#8221;, 90),
            new Student( &#8220;Computer&#8221;, &#8220;Anne&#8221;, 21, &#8220;female&#8221;, 80),
            new Student(&#8221;Physics&#8221;, &#8220;Davis&#8221;, 21, &#8220;female&#8221;, 99)
    );
  
    System.out.println(&#8221;Serial processing results: &#8220; + getScoreByCollect(allStudents));
    System.out.println(&#8221;Parallel processing results: &#8220; + getScoreByParallelCollect(allStudents));
}
&#8203;
public static Integer getScoreByCollect(List&lt;Student&gt; allStudents) {
    return allStudents.stream().collect(new CustomCollector(Student::getScore));
}
&#8203;
public static Integer getScoreByParallelCollect(List&lt;Student&gt; allStudents) {
    return allStudents.stream().collect(new CustomCollector(Student::getScore));
}</code></pre></div><p>Output:</p><pre><code><span>Serial processing results: 10
Parallel processing results: 10</span></code></pre><p>It can be seen that the results of serial and parallel processing are consistent. Interested readers can also create more students for testing and will find that parallel processing is faster than serial processing.</p><h2><strong>Summary</strong></h2><p>This article provides an in-depth analysis of the use of the collect method. Among them, I personally think that the most useful thing is its grouping function, which can greatly simplify the amount of our code. Is it like writing a requirements document? I don&#8217;t know if you have mastered its usage after reading the article. If you have any questions, please feel free to share them in the comment area.</p><h2><strong>Source code address</strong></h2><p>Github: <a href="https://github.com/junfeng0828/JavaBasic">https://github.com/junfeng0828/JavaBasic</a></p><p>Directory: src/main/java/stream/CollectCase.java</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview</span></a></p>]]></content:encoded></item><item><title><![CDATA[One Article to Master Java Streams🔥]]></title><description><![CDATA[As titled]]></description><link>https://seabreeze0828.substack.com/p/one-article-to-master-java-streams</link><guid isPermaLink="false">https://seabreeze0828.substack.com/p/one-article-to-master-java-streams</guid><dc:creator><![CDATA[Dylan Smith]]></dc:creator><pubDate>Sat, 01 Aug 2026 02:16:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7Jgx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Jgx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Jgx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 424w, https://substackcdn.com/image/fetch/$s_!7Jgx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 848w, https://substackcdn.com/image/fetch/$s_!7Jgx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 1272w, https://substackcdn.com/image/fetch/$s_!7Jgx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Jgx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp" width="858" height="485" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:485,&quot;width&quot;:858,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47868,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://seabreeze0828.substack.com/i/209272586?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Jgx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 424w, https://substackcdn.com/image/fetch/$s_!7Jgx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 848w, https://substackcdn.com/image/fetch/$s_!7Jgx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 1272w, https://substackcdn.com/image/fetch/$s_!7Jgx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f590c79-8c75-4c4a-aebc-43de922e595b_858x485.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>In the previous article, <strong><a href="https://seabreeze0828.substack.com/p/java-the-clearest-lambda-explanation">Lambda expression in java</a></strong>, I briefly mentioned the use of Stream. In this article, we will explore it in depth. First, let&#8217;s take the familiar <code>Student</code> class as an example. Suppose there are a group of students:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;82a8f8c7-f556-46f3-b3f0-fa22110cbb01&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">@Getter
@AllArgsConstructor
public static class Student {
    private String name;
    private Integer age;
}

&#8203;List&lt;Student&gt; students = Lists.newArrayList(
    new Student(&#8221;Bob&#8221;, 18),
    new Student(&#8221;Ted&#8221;, 17),
    new Student(&#8221;Zeka&#8221;, 19));</code></pre></div><p>Now there is such a demand:</p><blockquote><p><em>Return students 18 and older from a given student list, in descending order of age, up to 2.</em></p></blockquote><p>In <strong>Java7 and earlier code</strong>, we will implement it in the following way:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;6f262ae2-9663-4888-b9f0-fe79108f33e1&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public List&lt;Student&gt; getTwoOldestStudents(List&lt;Student&gt; students) {
    List&lt;Student&gt; result = new ArrayList&lt;&gt;();
    // 1.Loop to determine the age of students, first filter out students who match the age
    for (Student student : students) {
      if (student.getAge() &gt;= 18) {
        result.add(student);
      }
    }

    // 2.Sort the list of eligible students by age
    result.sort((s1, s2) -&gt; s2.getAge() - s1.getAge());
    // 3.Determine the result size. If it is greater than 2, intercept the sublist of the first two data and return it.
    if (result.size() &gt; 2) {
      result = result.subList(0, 2);
    }
    return result;
}</code></pre></div><p>In <strong>Java8 and later versions</strong>, with the help of Stream, we can write the following code more elegantly:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;68c690f6-2f9c-434b-ab44-9ce2fc514943&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public List&lt;Student&gt; getTwoOldestStudentsByStream(List&lt;Student&gt; students) {
        return students.stream()
                .filter(s -&gt; s.getAge() &gt;= 18)
                .sorted((s1, s2) -&gt; s2.getAge() - s1.getAge())
                .limit(2)
                .collect(Collectors.toList());
    }</code></pre></div><p><strong>Differences between the two implementations:</strong></p><p>From a functional perspective, <strong>procedural code implementation couples collection elements, loop iterations, and various logical judgments, exposing too many details</strong>. As requirements change and become more complex in the future, procedural code will become difficult to understand and maintain.</p><p><strong>Functional solutions decouple code details and business logic.</strong> Similar to SQL statements, they express <strong>&#8220;what to do&#8221;</strong> rather than <strong>&#8220;how to do it&#8221;,</strong> allowing programmers to focus more on business logic and write more Clean, easy to understand and maintain code.</p><p>Based on my daily project practical experience, I have made a detailed summary of the core points, confusing usage, typical usage scenarios, etc. of Stream. I hope it can help everyone have a more comprehensive understanding of Stream and apply it to project development more efficiently.</p><h2><strong>First introduction to Stream</strong></h2><p>Java 8 adds the Stream feature, which enables users to manipulate data structures such as List and Collection in a functional and simpler way, and implements parallel computing without user awareness.</p><p>In a nutshell&#65292;to perform a computation, stream operations are composed into a <em>stream pipeline</em>. The Stream pipeline consists of the following three parts&#65306;</p><ul><li><p><strong>Create Stream</strong> (Create from source data, which may be an array, a collection, a generator function, an I/O channel, etc)&#65307;</p></li><li><p><strong>Intermediate Operations</strong> (There may be zero or more, which transform a stream into another stream, such as <code>filter(Predicate)</code> )</p></li><li><p><strong>Terminal Operation</strong> (which produces a result or side-effect, such as <code>count()</code> or <code>forEach(Consumer)</code>)</p></li></ul><p>The following diagram illustrates these processes:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rzBT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rzBT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 424w, https://substackcdn.com/image/fetch/$s_!rzBT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 848w, https://substackcdn.com/image/fetch/$s_!rzBT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 1272w, https://substackcdn.com/image/fetch/$s_!rzBT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rzBT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png" width="1155" height="355" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:355,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!rzBT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 424w, https://substackcdn.com/image/fetch/$s_!rzBT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 848w, https://substackcdn.com/image/fetch/$s_!rzBT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 1272w, https://substackcdn.com/image/fetch/$s_!rzBT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc7b9ae-e32a-4706-a83e-4b2d81c14283_1155x355.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each Stream pipeline operation type contains several API methods. Let&#8217;s first list the functions of each API method.</p><h3><strong>1. Start the pipeline</strong></h3><p>Mainly responsible for directly creating a new Stream, or creating a new Stream based on existing array, List, Set, Map and other collection type objects.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cova!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cova!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 424w, https://substackcdn.com/image/fetch/$s_!cova!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 848w, https://substackcdn.com/image/fetch/$s_!cova!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 1272w, https://substackcdn.com/image/fetch/$s_!cova!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cova!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png" width="1155" height="257" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:257,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!cova!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 424w, https://substackcdn.com/image/fetch/$s_!cova!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 848w, https://substackcdn.com/image/fetch/$s_!cova!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 1272w, https://substackcdn.com/image/fetch/$s_!cova!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9bc1787-14e8-44b9-b73c-4b5b344389c7_1155x257.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In addition to <code>Stream</code>, which is a stream of object references, there are primitive specializations for <code>IntStream</code>, <code>LongStream</code>, and <code>DoubleStream</code>, all of which are referred to as &#8220;streams&#8221; and conform to the characteristics and restrictions described here.</p><h3><strong>2.Intermediate pipeline</strong></h3><p>This step is responsible for processing the Stream and returning a new Stream object. Intermediate pipeline operations can be <strong>superimposed</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uUpK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uUpK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 424w, https://substackcdn.com/image/fetch/$s_!uUpK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 848w, https://substackcdn.com/image/fetch/$s_!uUpK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 1272w, https://substackcdn.com/image/fetch/$s_!uUpK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uUpK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png" width="1155" height="447" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:447,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!uUpK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 424w, https://substackcdn.com/image/fetch/$s_!uUpK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 848w, https://substackcdn.com/image/fetch/$s_!uUpK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 1272w, https://substackcdn.com/image/fetch/$s_!uUpK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe067fc6f-7d17-4855-ab28-a751f9918a4f_1155x447.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>3.Terminate pipeline</strong></h3><p>As the name implies, after terminating the pipeline operation, the Stream will end, and finally it may perform some logical processing, or return some execution result data as required.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZT6d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZT6d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 424w, https://substackcdn.com/image/fetch/$s_!ZT6d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 848w, https://substackcdn.com/image/fetch/$s_!ZT6d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 1272w, https://substackcdn.com/image/fetch/$s_!ZT6d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZT6d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png" width="1155" height="558" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:558,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ZT6d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 424w, https://substackcdn.com/image/fetch/$s_!ZT6d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 848w, https://substackcdn.com/image/fetch/$s_!ZT6d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 1272w, https://substackcdn.com/image/fetch/$s_!ZT6d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee4789c3-dec8-4c67-8733-c19aca6a6388_1155x558.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Stream API Detailed Usage</strong></h2><h3><strong>1.Create Stream</strong></h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a8820b0b-d11e-4732-b2e0-62858d6cd41f&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">//Stream.of, IntStream.of...
Stream nameStream = Stream.of(&#8221;Bob&#8221;, &#8220;Ted&#8221;, &#8220;Zeka&#8221;);
IntStream ageStream = IntStream.of(18, 17, 19);
&#8203;
//stream, parallelStream
Stream studentStream = students.stream();
        Stream studentParallelStream = students.parallelStream();</code></pre></div><p>In most cases, we create a Stream based on an existing collection list.</p><h3><strong>2.Intermediate Operations</strong></h3><p><em><strong>2.1 map</strong></em></p><p>Both <code>map</code> and <code>flatMap</code> are used to convert existing elements to other element types. The difference is:</p><ul><li><p><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">map </mark><strong><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">must be one-to-one</mark>,</strong> that is, each element can only be converted into a new element</p></li><li><p><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">flatMap </mark><strong><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">can be one-to-man</mark>y</strong>, that is, each element can be converted into one or more new elements</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wZpb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wZpb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 424w, https://substackcdn.com/image/fetch/$s_!wZpb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 848w, https://substackcdn.com/image/fetch/$s_!wZpb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 1272w, https://substackcdn.com/image/fetch/$s_!wZpb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wZpb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png" width="1155" height="310" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:310,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!wZpb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 424w, https://substackcdn.com/image/fetch/$s_!wZpb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 848w, https://substackcdn.com/image/fetch/$s_!wZpb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 1272w, https://substackcdn.com/image/fetch/$s_!wZpb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F688e0536-fa4b-4b30-9baa-07b6115854d9_1155x310.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let&#8217;s look at the map method first. The current requirements are as follows:</p><blockquote><p><em>Convert the previous list of student objects to a list of student names and output:</em></p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;4df4c640-8f75-4cff-b81c-58f0ff06db1f&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">/**
     * Use of map: one-to-one   
     * @param students
     * @return
     */
    public List&lt;String&gt; objectToString(List&lt;Student&gt; students) {
        return students.stream()
                .map(Student::getName)
                .collect(Collectors.toList());
    }</code></pre></div><p>Output&#65306;</p><pre><code><span>[Bob, Ted, Zeka]</span></code></pre><p>As you can see, there are three Students in the input, and there will be three Student names in the output.</p><p><em><strong>2.2 flatMap</strong></em></p><p>Now let&#8217;s expand the requirements.</p><blockquote><p><em>The school requires every student to join a team. Suppose Bob, Ted, and Zeka join the basketball team. Alan, Anne, and Davis join the football team.</em></p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;141253f0-7152-4502-af3b-c65efade239a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">@Getter
@AllArgsConstructor
public static class Team {
    private String type;
    private List&lt;Student&gt; students;
}
&#8203;
List&lt;Student&gt; basketballStudents = Lists.newArrayList(
                new Student(&#8221;Bob&#8221;, 18),
                new Student(&#8221;Ted&#8221;, 17),
                new Student(&#8221;Zeka&#8221;, 19));
&#8203;
List&lt;Student&gt; footballStudent = Lists.newArrayList(
                new Student(&#8221;Alan&#8221;, 19),
                new Student(&#8221;Anne&#8221;, 21),
                new Student(&#8221;Davis&#8221;, 21));
&#8203;
Team basketballTeam = new Team(&#8221;bastetball&#8221;, basketballStudents);
Team footballTeam = new Team(&#8221;football&#8221;, footballStudent);
List&lt;Team&gt; teams = Lists.newArrayList(basketballTeam, footballTeam);    //Lists Object depends on the com.google.common.collect</code></pre></div><p>Now we need to count the students in all teams and return them in a merged list. How would you implement this requirement?</p><p>We try to use the map method to achieve it, as follows:</p><pre><code><span>List&lt;List&lt;Student&gt;&gt; allStudents = teams.stream()
    .map(Team::getStudents)
    .collect(Collectors.toList());</span></code></pre><p>We can see that if it is unsuccessful, the returned result type is List&lt;List&lt;Student&gt;&gt;, and what we want is actually List&lt;Student&gt;.</p><p>However, we can easily solve this problem in Java7 and previous versions, as follows:</p><pre><code><span>List&lt;Student&gt; allStudents = new ArrayList&lt;&gt;();
for (Team team : teams) {
    for (Student student : team.getStudents()) {
      allStudents.add(student);
    }
}</span></code></pre><p>But this code with two nested for loops is not elegant. Faced with this demand, flatMap can come into play.</p><pre><code><span>List&lt;Student&gt; allStudents = teams.stream()
    .flatMap(</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>t -&gt; t.getStudents().stream()</span></mark><span>)
    .collect(Collectors.toList());</span></code></pre><p>Do you think it&#8217;s cool? It&#8217;s done in one line of code. The flatMap method accepts a lambda expression function. The return value of the function must be a stream type. The flatMap method will eventually merge all the returned streams to generate a new Stream, but the map method cannot do this.</p><p>The following diagram clearly illustrates the processing logic of flatMap:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lnMU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lnMU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 424w, https://substackcdn.com/image/fetch/$s_!lnMU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 848w, https://substackcdn.com/image/fetch/$s_!lnMU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 1272w, https://substackcdn.com/image/fetch/$s_!lnMU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lnMU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png" width="1155" height="273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:273,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!lnMU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 424w, https://substackcdn.com/image/fetch/$s_!lnMU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 848w, https://substackcdn.com/image/fetch/$s_!lnMU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 1272w, https://substackcdn.com/image/fetch/$s_!lnMU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c80309-6a34-479e-8b58-95cd641d32d2_1155x273.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em><strong>2.3 filter, distinct, sorted, limit</strong></em></p><p>These are commonly used Stream intermediate operation methods. They are often used together. For specific function descriptions, you can see the previous table. Let&#8217;s look directly at the requirements this time:</p><blockquote><p><em>Regarding the list of students in all teams just now, we now need to know the ages of the second and third oldest among these students. They need to be at least 18 years old. In addition, if there are duplicates, they can only be counted as one.</em></p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;7a57b3f7-39cc-4c83-9bed-9c04571e5f94&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">List&lt;Integer&gt; topTwoAges = allStudents.stream() /
      .map(Student::getAge) //[18, 17, 19, 19, 21, 21]
      .filter(a -&gt; a &gt;= 18) //[18, 19, 19, 21, 21]
      .distinct()   //[18, 19, 21]
      .sorted((a1, a2) -&gt; a2 - a1)  //
      .skip(1)  //[19, 18]
      .limit(2) //[19, 18]
      .collect(Collectors.toList());
    
System.out.println(topTwoAges);</code></pre></div><p>Output&#65306;</p><pre><code><span>[19, 18]</span></code></pre><p><strong>Note</strong>&#65306;Since there are only two elements left after the <code>skip</code> method operation, the <code>limit</code> step can actually be omitted.</p><p>I believe you can clearly understand the functions of these methods without much explanation. It is highly recommended that you take the initiative to code and try it yourself!</p><p><em><strong>2.4 peek, foreach</strong></em></p><p>Both the <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">peek method and the foreach method</mark> can be <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">used to traverse elements and process them one by one</mark>, so we will put them together for comparison and explanation. <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">But it is worth noting that peek is an intermediate operation method and foreach is a terminal operation method.</mark></p><p>As described before, the intermediate operation can only be used as a processing step in the middle of the Stream pipeline. It cannot be executed directly to get the result. It must be executed later with the cooperation of a terminal operation. As a terminal method with no return value, foreach can perform the corresponding operation directly.</p><blockquote><p><em>For example, we say hello, xxx&#8230; to each student on the basketball team using peek and foreach respectively.</em></p></blockquote><pre><code><span>//peak
System.out.println(&#8221;------start peek------&#8221;);
basketballTeam.getStudents().stream().peek(s -&gt; System.out.println(&#8221;Hello, &#8220; + s.getName()));
System.out.println(&#8221;------end peek------&#8221;);
&#8203;
System.out.println();
//foreach
System.out.println(&#8221;------start foreach------&#8221;);
basketballTeam.getStudents().stream().forEach(s -&gt; System.out.println(&#8221;Hello, &#8220; + s.getName()));
System.out.println(&#8221;------end foreach------&#8221;);</span></code></pre><p>As can be seen from the output, <code>peek</code> is not executed when called alone, while <code>foreach</code> can be executed directly:</p><pre><code><span>------start peek------
------end peek------
&#8203;
------start foreach------
Hello, Bob
Hello, Ted
Hello, Zeka
------end foreach------</span></code></pre><p>If you <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">add a terminal operation after peek</mark>, it can be executed.</p><pre><code><span>System.out.println(&#8221;------start peek------&#8221;);
basketballTeam.getStudents().stream().peek(s -&gt; System.out.println(&#8221;Hello, &#8220; + s.getName())).count();
System.out.println(&#8221;------end peek------&#8221;);
&#8203;
//output
------start peek------
Hello, Bob
Hello, Ted
Hello, Zeka
------end peek------</span></code></pre><p>It is worth mentioning that peek should be used with caution to carry business processing logic.Think about it, as long as there is a termination method, will the peek method be executed?<strong>Uncertain! Look at the version, look at the scene!</strong></p><p>For example, in the Java8 version, the peek method just now will be executed normally, but in Java17 it will be automatically optimized and the logic in the peek will not be executed.As for the reason, you can take a look at the <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html">JDK17 official API documentation</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WmH1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WmH1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 424w, https://substackcdn.com/image/fetch/$s_!WmH1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 848w, https://substackcdn.com/image/fetch/$s_!WmH1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 1272w, https://substackcdn.com/image/fetch/$s_!WmH1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WmH1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png" width="1155" height="493" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:493,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!WmH1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 424w, https://substackcdn.com/image/fetch/$s_!WmH1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 848w, https://substackcdn.com/image/fetch/$s_!WmH1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 1272w, https://substackcdn.com/image/fetch/$s_!WmH1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6be17e-0b04-4184-824d-6d9b6e2a29db_1155x493.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Because for methods such as <code>findFirst</code> and <code>count</code>, the peek method will be regarded as an operation that is not related to the result, so it is directly optimized and not executed.</p><p>We can see from the comments of peek&#8217;s source code that the recommended usage scenario of peek is for some debugging scenarios. You can use peek to print out the information of each element to facilitate debugging and problem location analysis during the development process. Just like the name peek, it seems that it is just to peek at the changes in data during execution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HWo7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HWo7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 424w, https://substackcdn.com/image/fetch/$s_!HWo7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 848w, https://substackcdn.com/image/fetch/$s_!HWo7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 1272w, https://substackcdn.com/image/fetch/$s_!HWo7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HWo7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png" width="1155" height="691" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:691,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!HWo7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 424w, https://substackcdn.com/image/fetch/$s_!HWo7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 848w, https://substackcdn.com/image/fetch/$s_!HWo7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 1272w, https://substackcdn.com/image/fetch/$s_!HWo7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2bb116a-0a9b-4925-9377-b499695cdf76_1155x691.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3><strong>3.Terminal Operation</strong></h3><p>Here we divide terminal operations into two categories.</p><p>One type is to obtain simple results, mainly including <code>max</code>, <code>min</code>, <code>count</code>, <code>findAny</code>, <code>findFirst</code>, <code>anyMatch</code>, <code>allMatch</code> and other methods; the so-called simple means that the result form is Numbers, Boolean values, or Optional object values, etc.</p><p>The other type is the result collection type. Most scenarios are to obtain the result object of a collection class, such as List, Set or HashMap, etc., which are mainly implemented by the <code>collect</code> method.</p><p><em><strong>3.1 Simple result types</strong></em></p><p><em><strong>&#65288;1&#65289;max, min</strong></em></p><p>max() and min() are mainly used to return the maximum/minimum value of the element after stream processing. The return result is packaged by Optional. For the use of Optional, please refer to the previous article, <a href="https://medium.com/@junfeng0828/lambda-combined-with-optional-makes-javas-handling-of-null-more-elegant-b858cda16f69">Lambda combined with Optional makes Java&#8217;s handling of null more elegant</a>.</p><p>Let&#8217;s look directly at the example</p><blockquote><p><em>Tell me who are the oldest and youngest on the football team?</em></p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;9547403a-be46-458f-8ce7-d773008e96e7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">//max
footballTeam.getStudents().stream()
    .map(Student::getAge)
    .max(Comparator.comparing(a -&gt; a))
    .ifPresent(a -&gt; System.out.println(&#8221;The maximum age for a football team is &#8220; + a));</code></pre></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;6e04a2e3-4865-40ad-af2d-9886438e88b9&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">//min
footballTeam.getStudents().stream()
    .map(Student::getAge)
    .min(Comparator.comparing(a -&gt; a))
    .ifPresent(a -&gt; System.out.println(&#8221;The minimum age for a football team is &#8220; + a));</code></pre></div><p>Output:</p><pre><code><span>The maximum age for a football team is 21
The minimum age for a football team is 19</span></code></pre><p><em><strong>&#65288;2&#65289;findAny, findFirst</strong></em></p><p>findAny(), findFirst() are mainly used to terminate stream processing when an element that meets the conditions is found. findAny() is the same as findFirst for serial Stream and<strong> more efficient for parallel Stream.</strong></p><p>Assume that the basketball team has a new student, Tom, who is 19 years old.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;e644ed53-2895-4f45-af2a-d97f14928c83&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">List&lt;Student&gt; basketballStudents = Lists.newArrayList(
                new Student(&#8221;Bob&#8221;, 18),
                new Student(&#8221;Ted&#8221;, 17),
                new Student(&#8221;Zeka&#8221;, 19),
&#9;        new Student(&#8221;Tom&#8221;, 19));</code></pre></div><p>Take a look at the results of the following two requirements</p><ol><li><p>Return the name of the first student on the basketball team whose age is 19;</p></li><li><p>Return the name of any student on the basketball team who is 19 years old;</p></li></ol><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;c632db85-f382-4d9f-8e22-a15d9ce28140&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">//findFirst
basketballStudents.stream()
    .filter(s -&gt; s.getAge() == 19)
    .findFirst()
    .map(Student::getName)
    .ifPresent(name -&gt; System.out.println(&#8221;findFirst: &#8220; + name));</code></pre></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;02428695-f3c3-4f4d-af70-5bdc3912402f&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">//findAny
basketballStudents.stream()
    .filter(s -&gt; s.getAge() == 19)
    .findAny()
    .map(Student::getName)
    .ifPresent(name -&gt; System.out.println(&#8221;findAny: &#8220; + name));</code></pre></div><p>Output&#65306;</p><pre><code><span>findFirst: Zeka
findAny: Zeka</span></code></pre><p>It can be seen that there is no difference between the two functions under serial Stream.The differences in parallel processing will be introduced later.</p><p><em><strong>&#65288;3&#65289;count</strong></em></p><blockquote><p><em>Since a new student has been added to the basketball team, how many students are there in the basketball team now?</em></p></blockquote><pre><code><span>System.out.println(&#8221;The number of students on the basketball team: &#8220; + basketballStudents.stream().count());</span></code></pre><p>Output:</p><pre><code><span>The number of students on the basketball team: 4</span></code></pre><p><em><strong>&#65288;4&#65289;anyMatch, allMatch, noneMatch</strong></em></p><p>As the names suggest, these three methods are used to determine whether the element meets the conditions and return a boolean value. Look at the following three examples</p><ol><li><p>Is there a student named Alan on the football team?</p></li><li><p>Are all students on the football team under 22 years old?</p></li><li><p>Are there no students on the football team who are over 20 years old?</p></li></ol><pre><code><span>//anymatch
System.out.println(&#8221;anymatch: &#8220;
                   + footballStudent.stream().anyMatch(s -&gt; s.getName().equals(&#8221;Alan&#8221;)));</span></code></pre><pre><code><span>//allmatch
System.out.println(&#8221;allmatch: &#8220;
                   + footballStudent.stream().allMatch(s -&gt; s.getAge() &lt; 22));//nonematch
System.out.println(&#8221;noneMatch: &#8220;
                   + footballStudent.stream().noneMatch(s -&gt; s.getAge() &gt; 20));</span></code></pre><p>Output:</p><pre><code><span>anymatch: true
allmatch: true
noneMatch: false</span></code></pre><h3><strong>3.2 Result collection types</strong></h3><p><em><strong>&#65288;1&#65289;Generate a collection</strong></em></p><p>Generating collections should be considered the most commonly used scenario of collect. In addition to the List mentioned before, Sets, Maps, etc. can also be produced, as follows:</p><pre><code><span>//Get the latest student age distribution for the basketball team, no duplicates allowed
Set&lt;Integer&gt; ageSet = basketballStudents.stream().map(Student::getAge).collect(Collectors.toSet());
System.out.println(&#8221;set: &#8220; + ageSet);</span></code></pre><pre><code><span>//Get a map of the names and ages of all students on the basketball team
Map&lt;String, Integer&gt; nameAndAgeMap = basketballStudents.stream().collect(</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>Collectors.toMap(Student::getName, Student::getAge));</span></mark><span>
System.out.println(&#8221;map: &#8220; + nameAndAgeMap);</span></code></pre><p>Output:</p><pre><code><span>set: [17, 18, 19]
map: {Ted=17, Tom=19, Bob=18, Zeka=19}</span></code></pre><p><em><strong>(2) Generate concatenated strings</strong></em></p><p>In addition to generating collections, <code>collect</code> can also be used to <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">concatenate strings</mark>.</p><p>For example, after we get the names of all students on the basketball team, we hope to use &#8220;,&#8221; to splice all the names and return a String.</p><pre><code><span>System.out.println(basketballStudents.stream().map(Student::getName).collect(</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>Collectors.joining(&#8221;,&#8221;)</span></mark><span>));</span></code></pre><p>Output:</p><pre><code><span>Bob,Ted,Zeka,Tom</span></code></pre><p>Maybe you will say, can&#8217;t you use <code>String.join()</code> to achieve this function? There is no need to use <code>stream</code> to achieve this. It should be stated here that <strong>the charm of </strong><code>Stream</code><strong> is that it can be combined with other business logic for processing</strong>, making the code logic more natural and coherent. If it is purely a request for String string splicing, there is really no need to use <code>Stream</code> to achieve it. After all, there is no need to kill a chicken with a big knife!</p><p>In addition, Collectors.joining() also supports defining prefixes and suffixes, which is more powerful.</p><pre><code><span>System.out.println(basketballStudents.stream().map(Student::getName).collect(</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>Collectors.joining(&#8221;,&#8221;, &#8220;(&#8221;,&#8221;)&#8221;))</span></mark><span>);</span></code></pre><p>Output:</p><pre><code><span>(Bob,Ted,Zeka)</span></code></pre><p><em><strong>(3) Generate statistical results</strong></em></p><p>There is another scenario that may be rarely used in practice, which is to use <code>collect</code> to generate the sum of digital data. Let&#8217;s take a brief look at it.</p><pre><code><span>//Calculate average
System.out.println(&#8221;average age: &#8220;
                + basketballStudents.stream().map(Student::getAge).collect(</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>Collectors.averagingInt(a -&gt; a)</span></mark><span>));&#12289;</span></code></pre><pre><code><span>//Summary statistics
IntSummaryStatistics summary = basketballStudents.stream()
    .map(Student::getAge)
    .collect(</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>Collectors.summarizingInt(a -&gt; a)</span></mark><span>);
System.out.println(&#8221;summary: &#8220; + summary);</span></code></pre><p>In the above example, using <code>collect</code> to perform some mathematical operations on age, the results are as follows:</p><pre><code><span>average age: 18.0
summary: </span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>IntSummaryStatistics{count=3, sum=54, min=17, average=18.000000, max=19}</span></mark></code></pre><h2><strong>Parallel Stream</strong></h2><h3><strong>Mechanism description</strong></h3><p>Using parallel streams can effectively utilize computer performance and improve logic execution speed. Parallel Stream divides an entire stream into multiple fragments, then executes processing logic on each fragmented stream in parallel, and finally summarizes the execution results of each fragmented stream into an entire Stream.</p><p>As shown in the diagram below, filter for numbers greater than or equal to 18:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xQNc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xQNc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 424w, https://substackcdn.com/image/fetch/$s_!xQNc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 848w, https://substackcdn.com/image/fetch/$s_!xQNc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 1272w, https://substackcdn.com/image/fetch/$s_!xQNc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xQNc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png" width="1155" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xQNc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 424w, https://substackcdn.com/image/fetch/$s_!xQNc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 848w, https://substackcdn.com/image/fetch/$s_!xQNc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 1272w, https://substackcdn.com/image/fetch/$s_!xQNc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11634d9-4fa5-41b7-aafd-d7742fe0e176_1155x283.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong>Use findAny() efficiently</strong></h3><p>As mentioned before, <mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">findAny() is more efficient in Parallel Stream</mark>, and it can be seen from the API documentation that the results of each execution of this method may be different.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1DkI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1DkI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 424w, https://substackcdn.com/image/fetch/$s_!1DkI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 848w, https://substackcdn.com/image/fetch/$s_!1DkI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 1272w, https://substackcdn.com/image/fetch/$s_!1DkI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1DkI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png" width="1155" height="775" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7053931-f403-45b4-a429-59c829bae775_1155x775.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:775,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!1DkI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 424w, https://substackcdn.com/image/fetch/$s_!1DkI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 848w, https://substackcdn.com/image/fetch/$s_!1DkI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 1272w, https://substackcdn.com/image/fetch/$s_!1DkI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7053931-f403-45b4-a429-59c829bae775_1155x775.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We try to execute findAny() 10 times using parallelStream to find any student name that satisfies the criteria of Bob, Tom, and Zeka.</p><pre><code><span>for (int i = 0; i &lt; 10; i++) {
    basketballStudents.</span><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"><span>parallelStream</span></mark><span>()
        .filter(s -&gt; s.getAge() &gt;= 18)
        .findAny()
        .map(Student::getName)
        .ifPresent(name -&gt; System.out.println(&#8221;findAny in parallel stream: &#8220; + name));
}</span></code></pre><p>Output:</p><pre><code><span>findAny in parallel stream: Zeka
findAny in parallel stream: Zeka
findAny in parallel stream: Tom
findAny in parallel stream: Zeka
findAny in parallel stream: Zeka
findAny in parallel stream: Bob
findAny in parallel stream: Zeka
findAny in parallel stream: Zeka
findAny in parallel stream: Zeka
findAny in parallel stream: Zeka</span></code></pre><p>This output confirms the<mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);"> instability of findAny()</mark>.</p><p>For more information about Parallel Stream, I will further analyze and discuss it in a later article.</p><h2><strong><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">Additional</mark> information</strong></h2><h3><strong>1. Delayed execution</strong></h3><p>Streams are lazy; calculations on source data are only performed when a terminal operation is initiated, and source elements are consumed only when needed. For example, the peek method mentioned before in the article is a good example.</p><h3><strong>2. Avoid performing terminal operations twice</strong></h3><p>It is necessary to add a reminder here. Once a Stream is terminated, it cannot be used to perform other operations later, otherwise an error will be reported. See the following example:</p><pre><code><span>Stream&lt;Student&gt; studentStream = basketballStudents.stream().filter(s -&gt; s.getAge() == 19);
// Calculate the number of students
System.out.println(&#8221;the number of students: &#8220; + studentStream.count());
// If you try it again, an error will be reported
try {
    System.out.println(&#8221;the number of students: &#8220; + studentStream.count());
} catch (Exception e) {
    e.printStackTrace();
}</span></code></pre><p>Output:</p><pre><code><span>the number of students: 2
java.lang.IllegalStateException: stream has already been operated upon or closed
&#9;&#9;&#9;at java.util.stream.AbstractPipeline.&lt;init&gt;(AbstractPipeline.java:203)
&#9;&#9;&#9;...</span></code></pre><h2><strong>Summarize</strong></h2><p>This article introduces how to use Stream to write more elegant code through multiple cases, and briefly introduces the actual role of each API. Due to space limitations, this article only briefly introduces the usage of <code>collect</code> and Parallel Stream. I will discuss them in depth in subsequent articles.</p><p>In addition, if you want to master Stream, it is not enough to look at it, but also need to practice in the project. If you have any questions, please feel free to discuss them in the comments section!</p><h3><strong><mark data-color="rgb(232, 243, 232)" style="background-color: rgb(232, 243, 232); color: rgb(0, 0, 0);">Source code</mark> address</strong></h3><p>Github: <a href="https://github.com/junfeng0828/JavaBasic">https://github.com/junfeng0828/JavaBasic</a></p><p>Directory: src/main/java/stream/StreamCase.java</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview</span></a></p><p><em><strong>If this post has helped you out in any way, I&#8217;d truly appreciate you becoming a paid subscriber. Your ongoing support keeps me motivated to keep crafting more thorough, high-quality technical content down the line. Thank you so much.</strong></em></p>]]></content:encoded></item><item><title><![CDATA[Java: The Clearest Lambda Explanation You’ll Ever See]]></title><description><![CDATA[As titled]]></description><link>https://seabreeze0828.substack.com/p/java-the-clearest-lambda-explanation</link><guid isPermaLink="false">https://seabreeze0828.substack.com/p/java-the-clearest-lambda-explanation</guid><dc:creator><![CDATA[Dylan Smith]]></dc:creator><pubDate>Fri, 31 Jul 2026 13:23:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!YQxT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YQxT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YQxT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 424w, https://substackcdn.com/image/fetch/$s_!YQxT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 848w, https://substackcdn.com/image/fetch/$s_!YQxT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 1272w, https://substackcdn.com/image/fetch/$s_!YQxT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YQxT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png" width="708" height="389" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:389,&quot;width&quot;:708,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Lambda Expression&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Lambda Expression" title="Lambda Expression" srcset="https://substackcdn.com/image/fetch/$s_!YQxT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 424w, https://substackcdn.com/image/fetch/$s_!YQxT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 848w, https://substackcdn.com/image/fetch/$s_!YQxT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 1272w, https://substackcdn.com/image/fetch/$s_!YQxT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef30961-61ab-4ceb-a9de-416906b4e6dc_708x389.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>1.What is Lambda?</strong></h2><p>We know that for a Java variable, we can assign a &#8220;value&#8221; to it, and you can do something with it.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;87cdf7a2-8db4-4ff9-bae4-690e4bd8ab7d&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Integer a = 1;
String s = &#8220;Hello&#8221;;
System.out.println(s + a);</code></pre></div><p>What should you do if you want to assign a &#8220;piece of code&#8221; to a Java variable?</p><p>For example, I want to assign the block of code on the right to a Java variable called codeBlock:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Y08!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Y08!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 424w, https://substackcdn.com/image/fetch/$s_!0Y08!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 848w, https://substackcdn.com/image/fetch/$s_!0Y08!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 1272w, https://substackcdn.com/image/fetch/$s_!0Y08!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Y08!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png" width="752" height="146" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:146,&quot;width&quot;:752,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0Y08!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 424w, https://substackcdn.com/image/fetch/$s_!0Y08!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 848w, https://substackcdn.com/image/fetch/$s_!0Y08!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 1272w, https://substackcdn.com/image/fetch/$s_!0Y08!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1e5410d-57b6-47df-992b-07af2e2d553b_752x146.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>Before Java 8, this was not possible. But after the advent of Java 8, it can be done using the Lambda feature. The intuitive expression is as follows&#65306;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;4a8b8a5d-f580-4552-ba13-c1202e3bc3a0&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">codeBlock = public void doSomething(String s) {
        System.out.println(s);
}</code></pre></div><p>Of course, this is not a very concise way of writing. So, in order to make this assignment operation more elegant, we can remove some useless declarations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IphD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IphD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 424w, https://substackcdn.com/image/fetch/$s_!IphD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 848w, https://substackcdn.com/image/fetch/$s_!IphD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 1272w, https://substackcdn.com/image/fetch/$s_!IphD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IphD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png" width="766" height="1136" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1136,&quot;width&quot;:766,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!IphD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 424w, https://substackcdn.com/image/fetch/$s_!IphD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 848w, https://substackcdn.com/image/fetch/$s_!IphD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 1272w, https://substackcdn.com/image/fetch/$s_!IphD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab08588-3e43-428b-8390-9d48e2ca6e03_766x1136.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>In this way, we have successfully assigned a &#8220;piece of code&#8221; to a variable very elegantly. And &#8220;this piece of code&#8221;, or &#8220;this function assigned to a variable&#8221;, is a Lambda expression.</p><p>But there is still a question here, that is, what type should the variable codeBlock be?</p><p>In Java 8, all Lambda types are an interface, and the Lambda expression itself, that is, the &#8220;piece of code&#8221;, needs to be an implementation of this interface. This is one of the keys to understanding Lambda in my opinion. In short, the Lambda expression itself is the implementation of an interface. It might still be a bit confusing to say this directly, so let&#8217;s continue with examples. We add a type to codeBlock above:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WyWs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WyWs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 424w, https://substackcdn.com/image/fetch/$s_!WyWs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 848w, https://substackcdn.com/image/fetch/$s_!WyWs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 1272w, https://substackcdn.com/image/fetch/$s_!WyWs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WyWs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png" width="780" height="338" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:338,&quot;width&quot;:780,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!WyWs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 424w, https://substackcdn.com/image/fetch/$s_!WyWs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 848w, https://substackcdn.com/image/fetch/$s_!WyWs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 1272w, https://substackcdn.com/image/fetch/$s_!WyWs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19f96c0f-373d-45d0-880d-df58972f47a7_780x338.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This type of interface that has only one function to be implemented is called a &#8220;functional interface&#8221;.</p><p>In order to prevent later people from adding interface functions to this interface, which will cause multiple interface functions to be implemented and become a &#8220;non-functional interface&#8221;, we can add a declaration @FunctionalInterface to this interface, so that others cannot add new functions to it.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PbRb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PbRb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 424w, https://substackcdn.com/image/fetch/$s_!PbRb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 848w, https://substackcdn.com/image/fetch/$s_!PbRb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 1272w, https://substackcdn.com/image/fetch/$s_!PbRb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PbRb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png" width="498" height="168" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:168,&quot;width&quot;:498,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!PbRb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 424w, https://substackcdn.com/image/fetch/$s_!PbRb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 848w, https://substackcdn.com/image/fetch/$s_!PbRb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 1272w, https://substackcdn.com/image/fetch/$s_!PbRb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedd81ee-5e43-43fe-9edf-200535fb1f93_498x168.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In this way, we get a complete Lambda expression declaration.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l379!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l379!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 424w, https://substackcdn.com/image/fetch/$s_!l379!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 848w, https://substackcdn.com/image/fetch/$s_!l379!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 1272w, https://substackcdn.com/image/fetch/$s_!l379!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l379!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png" width="712" height="134" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/590c6418-b588-4dbc-9e39-670f2e307157_712x134.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:134,&quot;width&quot;:712,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!l379!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 424w, https://substackcdn.com/image/fetch/$s_!l379!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 848w, https://substackcdn.com/image/fetch/$s_!l379!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 1272w, https://substackcdn.com/image/fetch/$s_!l379!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c6418-b588-4dbc-9e39-670f2e307157_712x134.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2><strong>2.What is The Function of Lambda Expression?</strong></h2><p>The most intuitive effect is to make the code extremely concise.</p><p>We can compare Lambda expressions and traditional Java implementations of the same interface:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BiPD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BiPD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 424w, https://substackcdn.com/image/fetch/$s_!BiPD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 848w, https://substackcdn.com/image/fetch/$s_!BiPD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 1272w, https://substackcdn.com/image/fetch/$s_!BiPD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BiPD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png" width="1155" height="363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b386eebc-0666-4218-ad72-a209431c523b_1155x363.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:363,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!BiPD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 424w, https://substackcdn.com/image/fetch/$s_!BiPD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 848w, https://substackcdn.com/image/fetch/$s_!BiPD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 1272w, https://substackcdn.com/image/fetch/$s_!BiPD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb386eebc-0666-4218-ad72-a209431c523b_1155x363.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These two ways of writing are essentially equivalent. But obviously, the way of writing in Java 8 is more elegant and concise. Moreover, since Lambda can be directly assigned to variables, we can directly pass Lambda as a parameter to the function, while traditional Java must have clear interface implementation and initialization definition:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CPZO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CPZO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 424w, https://substackcdn.com/image/fetch/$s_!CPZO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 848w, https://substackcdn.com/image/fetch/$s_!CPZO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 1272w, https://substackcdn.com/image/fetch/$s_!CPZO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CPZO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png" width="1155" height="422" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:422,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!CPZO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 424w, https://substackcdn.com/image/fetch/$s_!CPZO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 848w, https://substackcdn.com/image/fetch/$s_!CPZO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 1272w, https://substackcdn.com/image/fetch/$s_!CPZO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfddb511-68a4-49ce-992a-cf971716ce13_1155x422.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In some cases, this interface implementation only needs to be used once. Traditional Java 7 requires you to define a &#8220;polluting environment&#8221; interface to implement InterfaceImpl. In comparison, Java 8&#8217;s Lambda appears much cleaner.</p><p>Lambda combines FunctionalInterface Lib, forEach, stream(), method reference and other new features to make the code more concise!</p><p>Let&#8217;s go directly to the example.</p><p>Assume that the definition of Student and the value of List(Student) are given.</p><pre><code><span>@Getter
@AllArgsConstructor
public static class Student {
  private String name;
  private Integer age;
}
&#8203;
List&lt;Student&gt; students = Arrays.asList(
  new Student(&#8221;Bob&#8221;, 18),
  new Student(&#8221;Ted&#8221;, 17),
  new Student(&#8221;Zeka&#8221;, 18));</span></code></pre><p>Now you need to print out the names of all 18-year-old students in <code>students</code>.</p><p>Original Lambda writing method: define two functional interfaces, define a static function, call the static function and assign Lambda expressions to the parameters.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;typescript&quot;,&quot;nodeId&quot;:&quot;ad98f6a9-c8f2-42ad-a69e-10725b282fef&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-typescript">@FunctionalInterfaceinterface AgeMatcher {
  boolean match(Student student);
}
&#8203;
@FunctionalInterface
interface Executor {
  boolean execute(Student student);
}
&#8203;
public static void matchAndExecute(List&lt;Student&gt; students, AgeMatcher matcher, Executor executor) {
  for (Student student : students) {
    if (matcher.match(student)) {
      executor.execute(student);
    }
  }
}
&#8203;
public static void main(String[] args) {
&#8203;
        List&lt;Student&gt; students = Arrays.asList(
                new Student(&#8221;Bob&#8221;, 18),
                new Student(&#8221;Ted&#8221;, 17),
                new Student(&#8221;Zeka&#8221;, 18));
&#8203;
        matchAndExecute(students, 
                        s -&gt; s.getAge() == 18, 
                        s -&gt; System.out.println(s.getName()));
}</code></pre></div><p>This code is actually relatively concise, but can we be more concise?</p><p>Of course, there is a functional interface package in Java 8, which defines a large number of functional interfaces that may be used (java.util.function (Java Platform SE 8)).</p><p>Therefore, we don&#8217;t need to define the two functional interfaces AgeMatcher and Executor here at all. We can just use Predicate(T) and Consumer(T) in the Java 8 functional interface package because of their pair of interfaces. The definition is actually the same as AgeMatcher/Executor.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p_nk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p_nk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 424w, https://substackcdn.com/image/fetch/$s_!p_nk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 848w, https://substackcdn.com/image/fetch/$s_!p_nk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 1272w, https://substackcdn.com/image/fetch/$s_!p_nk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p_nk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png" width="1134" height="524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:524,&quot;width&quot;:1134,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!p_nk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 424w, https://substackcdn.com/image/fetch/$s_!p_nk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 848w, https://substackcdn.com/image/fetch/$s_!p_nk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 1272w, https://substackcdn.com/image/fetch/$s_!p_nk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7971ad80-f813-4fbb-bd0e-e51209d28575_1134x524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Step 1:</strong> Simplify &#8212; Utilize functional interface packages:</p><pre><code><span>public static void matchAndExecute(List&lt;Student&gt; students, Predicate&lt;Student&gt; predicate, Consumer&lt;Student&gt; consumer) {
        for (Student student : students) {
            if (predicate.test(student)) {
                consumer.accept(student);
            }
        }
    }</span></code></pre><p>The for each loop in matchAndExecute is actually very annoying. Here you can use Iterable&#8217;s own forEach() instead. forEach() itself can accept a Consumer(T) parameter.</p><p><strong>Step 2:</strong> Simplify &#8212; Replace the foreach loop with Iterable.forEach() :</p><pre><code><span>public static void matchAndExecute(List&lt;Student&gt; students, Predicate&lt;Student&gt; predicate, Consumer&lt;Student&gt; consumer) {
        students.forEach(s -&gt; {
            if (predicate.test(s)) {
                consumer.accept(s);
            }
        });
    }</span></code></pre><p>Since <code>matchAndExecute</code> is actually just an operation on the List, here we can get rid of <code>matchAndExecute</code> and directly use the stream() feature to complete it. Several methods of stream() accept parameters such as Predicate(T) and Consumer(T) (java.util.stream (Java Platform SE 8)). Once you understand the above content, stream() is very easy to understand and does not require any further explanation.</p><p><strong>Step 3:</strong> Simplify &#8212; use stream() instead of static functions:</p><pre><code><span>students.stream()
        .filter(s -&gt; s.getAge() == 18)
        .forEach(s -&gt; System.out.println(s.getName()));</span></code></pre><p>Compared with the original Lambda writing method, this is very concise. But if we ask for a change to print all the information of the student, and s -&gt; System.out.println(s); then we can use Method reference to continue simplification. The so-called Method reference is to replace the Lambda expression with the method of other Object/Class that has been written. The format is as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pcmj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pcmj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 424w, https://substackcdn.com/image/fetch/$s_!pcmj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 848w, https://substackcdn.com/image/fetch/$s_!pcmj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 1272w, https://substackcdn.com/image/fetch/$s_!pcmj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pcmj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png" width="1136" height="254" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:254,&quot;width&quot;:1136,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pcmj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 424w, https://substackcdn.com/image/fetch/$s_!pcmj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 848w, https://substackcdn.com/image/fetch/$s_!pcmj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 1272w, https://substackcdn.com/image/fetch/$s_!pcmj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aaecce5-6a7f-4a55-b395-d39ceb423ae2_1136x254.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Step 4:</strong> Simplify &#8212; You can use Method reference instead of the Lambda expression in forEach:</p><pre><code><span>students.stream()
&#9;.filter(s -&gt; s.getAge() == 18)
        .map(Student::getName)
&#9;.forEach(System.out::println);</span></code></pre><p>This is basically the most concise version I can write.</p><p>There is still something to discuss and learn about Lambda in Java. For example, how to use the characteristics of Lambda to perform parallel processing, etc.</p><p>In short, I am just giving you a general introduction to give you an idea. There are many related tutorials about Lambda on the Internet, read more and practice more. As time goes by, there will definitely be improvements.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://seabreeze0828.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Java, SpringBoot &amp; AI Development: Coding Skills &amp; Interview</span></a></p><p><em><strong>If this post has helped you out in any way, I&#8217;d truly appreciate you becoming a paid subscriber. Your ongoing support keeps me motivated to keep crafting more thorough, high-quality technical content down the line. Thank you so much.</strong></em></p>]]></content:encoded></item></channel></rss>