<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: TheCodeForge</title>
    <description>The latest articles on Forem by TheCodeForge (@thecodeforge).</description>
    <link>https://forem.com/thecodeforge</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3810173%2Fb5fe31f8-2a0f-45d7-96d6-3b4e29898aa7.png</url>
      <title>Forem: TheCodeForge</title>
      <link>https://forem.com/thecodeforge</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thecodeforge"/>
    <language>en</language>
    <item>
      <title>EnumMap and EnumSet: The Java Collections Most Developers Never Use</title>
      <dc:creator>TheCodeForge</dc:creator>
      <pubDate>Wed, 29 Apr 2026 13:07:21 +0000</pubDate>
      <link>https://forem.com/thecodeforge/enummap-and-enumset-the-java-collections-most-developers-never-use-15e2</link>
      <guid>https://forem.com/thecodeforge/enummap-and-enumset-the-java-collections-most-developers-never-use-15e2</guid>
      <description>&lt;p&gt;Two years ago I was doing a code review and flagged a colleague's&lt;br&gt;
&lt;code&gt;HashMap&amp;lt;OrderStatus, Handler&amp;gt;&lt;/code&gt; as "fine, no issues." The tests passed.&lt;br&gt;
The code shipped.&lt;/p&gt;

&lt;p&gt;Last year I profiled that same service under load and found the map&lt;br&gt;
lookup on the hot path burning more CPU than it should. The fix was&lt;br&gt;
a one-line change. The only reason I knew about it was because I'd&lt;br&gt;
finally read the &lt;code&gt;java.util.EnumMap&lt;/code&gt; source out of curiosity one&lt;br&gt;
afternoon.&lt;/p&gt;

&lt;p&gt;This is that story, plus everything I now know about &lt;code&gt;EnumMap&lt;/code&gt; and&lt;br&gt;
&lt;code&gt;EnumSet&lt;/code&gt; that I wish someone had told me earlier.&lt;/p&gt;


&lt;h2&gt;
  
  
  The One Fact That Makes Everything Else Click
&lt;/h2&gt;

&lt;p&gt;Every Java enum constant has an ordinal — a zero-based integer&lt;br&gt;
assigned in declaration order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;OrderStatus&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;PLACED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// ordinal 0&lt;/span&gt;
    &lt;span class="no"&gt;CONFIRMED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ordinal 1&lt;/span&gt;
    &lt;span class="no"&gt;SHIPPED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// ordinal 2&lt;/span&gt;
    &lt;span class="no"&gt;DELIVERED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ordinal 3&lt;/span&gt;
    &lt;span class="no"&gt;CANCELLED&lt;/span&gt;  &lt;span class="c1"&gt;// ordinal 4&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ordinal is stable for a given JVM session. It is the entire&lt;br&gt;
foundation that makes both &lt;code&gt;EnumMap&lt;/code&gt; and &lt;code&gt;EnumSet&lt;/code&gt; possible.&lt;/p&gt;


&lt;h2&gt;
  
  
  EnumMap: What's Actually Inside
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;java.util.EnumMap&lt;/code&gt; in your JDK source. The core storage field is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole map. A plain Java array. The index into that array&lt;br&gt;
is the enum constant's ordinal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;put(OrderStatus.SHIPPED, handler)&lt;/code&gt; stores &lt;code&gt;handler&lt;/code&gt; at &lt;code&gt;vals[2]&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
&lt;code&gt;get(OrderStatus.SHIPPED)&lt;/code&gt; reads &lt;code&gt;vals[2]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;hashCode()&lt;/code&gt;. No bucket array. No &lt;code&gt;Map.Entry&lt;/code&gt; objects. No collision&lt;br&gt;
chains. Just a direct array index read.&lt;/p&gt;

&lt;p&gt;Compare that to what &lt;code&gt;HashMap&lt;/code&gt; has to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call &lt;code&gt;key.hashCode()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Apply a spread function to reduce clustering&lt;/li&gt;
&lt;li&gt;Locate the bucket via &lt;code&gt;(n - 1) &amp;amp; hash&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Walk the bucket chain comparing keys with &lt;code&gt;.equals()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Potentially trigger a resize and full rehash&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For enum keys, all of that work is completely unnecessary.&lt;br&gt;
The ordinal already is a perfect compact hash. EnumMap just&lt;br&gt;
uses it directly.&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory difference
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;HashMap&lt;/code&gt; stores &lt;code&gt;Map.Entry&lt;/code&gt; objects — each one holds a key reference,&lt;br&gt;
a value reference, the hash code, and a &lt;code&gt;next&lt;/code&gt; pointer.&lt;br&gt;
That's 4 object fields per entry, plus the bucket array overhead.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EnumMap&lt;/code&gt; stores only values. The keys are implicit in the array&lt;br&gt;
position. For a 5-constant enum, an &lt;code&gt;EnumMap&lt;/code&gt; uses roughly 40–60%&lt;br&gt;
less heap per entry than the equivalent &lt;code&gt;HashMap&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating one
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Always requires the class literal — the array must be pre-sized&lt;/span&gt;
&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EnumMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PLACED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handlePlaced&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONFIRMED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handleConfirmed&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SHIPPED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handleShipped&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Copy constructor also works, which is useful for defensive copies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EnumMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;existingMap&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Iteration order
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;EnumMap&lt;/code&gt; always iterates in enum declaration order — not insertion&lt;br&gt;
order, not sorted order, declaration order. This is free: it's&lt;br&gt;
just incrementing an array index. No pointer chasing, no&lt;br&gt;
comparisons.&lt;/p&gt;
&lt;h3&gt;
  
  
  What it won't do
&lt;/h3&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; allow null keys. Attempting &lt;code&gt;put(null, value)&lt;/code&gt;&lt;br&gt;
throws &lt;code&gt;NullPointerException&lt;/code&gt; immediately. It &lt;em&gt;does&lt;/em&gt; allow null values.&lt;/p&gt;


&lt;h2&gt;
  
  
  Real Pattern: Routing by Status
&lt;/h2&gt;

&lt;p&gt;The cleanest use case I've found in production is replacing a&lt;br&gt;
&lt;code&gt;switch&lt;/code&gt; with an &lt;code&gt;EnumMap&lt;/code&gt; of handlers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;PaymentMethod&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;CREDIT_CARD&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;DEBIT_CARD&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;PAYPAL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CRYPTO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;BANK_TRANSFER&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentRouter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PaymentRouter&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;processors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EnumMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CREDIT_CARD&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;processCreditCard&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DEBIT_CARD&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;processDebitCard&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PAYPAL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;processPaypal&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CRYPTO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;processCrypto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BANK_TRANSFER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;processBankTransfer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Receipt&lt;/span&gt; &lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Payment&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMethod&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processor&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"No processor registered for: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMethod&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is more testable than a &lt;code&gt;switch&lt;/code&gt; (inject mock processors),&lt;br&gt;
safer than a &lt;code&gt;switch&lt;/code&gt; (compiler won't silently fall through),&lt;br&gt;
and the lookup is an array read instead of a branch table.&lt;/p&gt;


&lt;h2&gt;
  
  
  EnumSet: A 64-Element Set in 8 Bytes
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;EnumSet&lt;/code&gt; is abstract. The JDK gives you one of two implementations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;RegularEnumSet&lt;/code&gt;&lt;/strong&gt; — for enums with ≤ 64 constants. Stores the
entire set as a single &lt;code&gt;long&lt;/code&gt; using bit manipulation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;JumboEnumSet&lt;/code&gt;&lt;/strong&gt; — for enums with &amp;gt; 64 constants. Uses an array
of &lt;code&gt;long&lt;/code&gt; values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You never reference these classes. The static factory methods on&lt;br&gt;
&lt;code&gt;EnumSet&lt;/code&gt; return the right one automatically.&lt;/p&gt;
&lt;h3&gt;
  
  
  What's inside RegularEnumSet
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// that's the entire set&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One &lt;code&gt;long&lt;/code&gt;. 8 bytes. Each bit position corresponds to one enum&lt;br&gt;
constant's ordinal.&lt;/p&gt;

&lt;p&gt;For a &lt;code&gt;Permission&lt;/code&gt; enum where &lt;code&gt;READ&lt;/code&gt; has ordinal 0 and &lt;code&gt;WRITE&lt;/code&gt;&lt;br&gt;
has ordinal 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EnumSet containing READ        → elements = 0b...0001 = 1L
EnumSet containing READ, WRITE → elements = 0b...0011 = 3L
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;contains(Permission.READ)&lt;/code&gt; compiles down to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1L&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ordinal&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One bitwise AND. Single CPU instruction. The fastest possible&lt;br&gt;
&lt;code&gt;contains()&lt;/code&gt; check in Java.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;addAll(otherEnumSet)&lt;/code&gt; — union of two sets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;elements&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One bitwise OR. The entire operation completes in a single instruction&lt;br&gt;
regardless of how many elements are in the set. &lt;code&gt;retainAll&lt;/code&gt;&lt;br&gt;
(intersection) is &lt;code&gt;&amp;amp;=&lt;/code&gt;. &lt;code&gt;removeAll&lt;/code&gt; (difference) is &lt;code&gt;&amp;amp;= ~other&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For comparison: &lt;code&gt;HashSet.addAll()&lt;/code&gt; processes each element&lt;br&gt;
individually through the full hash pipeline. For a set with N elements,&lt;br&gt;
it takes O(N) hash computations. &lt;code&gt;EnumSet.addAll()&lt;/code&gt; is always O(1).&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating one
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;WRITE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;DELETE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ADMIN&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;AUDIT&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;EXPORT&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Specific elements&lt;/span&gt;
&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userPerms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WRITE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// All elements&lt;/span&gt;
&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allPerms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Empty, but typed&lt;/span&gt;
&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;noPerms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;noneOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Everything NOT in the given set&lt;/span&gt;
&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nonAdmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complementOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ADMIN&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// A range (inclusive both ends, in declaration order)&lt;/span&gt;
&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;basicPerms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DELETE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Null handling
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;EnumSet&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; allow null elements. &lt;code&gt;HashSet&lt;/code&gt; allows one null.&lt;br&gt;
This is a migration gotcha if you're replacing a &lt;code&gt;HashSet&lt;/code&gt; that&lt;br&gt;
has a null somewhere in it.&lt;/p&gt;


&lt;h2&gt;
  
  
  Real Pattern: Permission System
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Role&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;VIEWER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableSet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;EDITOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableSet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WRITE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;MANAGER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableSet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WRITE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                       &lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DELETE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EXPORT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthorizationService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;can&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userPerms&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Permission&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;userPerms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// single bitwise AND&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;canAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userPerms&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                          &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;userPerms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// single AND + compare to mask&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// single bitwise OR if b is also an EnumSet&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note the &lt;code&gt;Collections.unmodifiableSet()&lt;/code&gt; wrapper on the constants —&lt;br&gt;
more on why this matters in the mistakes section below.&lt;/p&gt;


&lt;h2&gt;
  
  
  Real Pattern: Replacing C-Style Bitmask Flags
&lt;/h2&gt;

&lt;p&gt;If you've ever maintained code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OPTION_COMPRESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;OPTION_ENCRYPT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;OPTION_CHECKSUM&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;OPTION_ENCRYPT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;EnumSet&lt;/code&gt; is the type-safe modern replacement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;ExportOption&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="no"&gt;COMPRESS&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ENCRYPT&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CHECKSUM&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;INCLUDE_METADATA&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;ExportConfig&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ExportConfig&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;ExportOption&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;COMPRESS&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;ExportOption&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ENCRYPT&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ExportOption&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ENCRYPT&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same performance (the implementation is the same &lt;code&gt;long&lt;/code&gt; bitmask),&lt;br&gt;
type safety, null safety, and readable names instead of integer&lt;br&gt;
literals.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Benchmark
&lt;/h2&gt;

&lt;p&gt;Here's a runnable JMH benchmark. The results below are from&lt;br&gt;
JDK 21, server VM, i7-class laptop, averaged over 10 measurement&lt;br&gt;
iterations with 5 warmup iterations and 2 forks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@BenchmarkMode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Mode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AverageTime&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@OutputTimeUnit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NANOSECONDS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@State&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Warmup&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Measurement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Fork&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EnumCollectionBenchmark&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;D&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;E&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;F&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;G&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;H&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// 8 constants&lt;/span&gt;

    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;enumSet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Setup&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;enumMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EnumMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;hashMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;enumSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;noneOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;hashSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enumMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ordinal&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;hashMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ordinal&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;enumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;enumMapGet&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;       &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;enumMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;E&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;hashMapGet&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;       &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;E&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;enumSetContains&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;enumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;E&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;hashSetContains&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;E&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;enumMapIterate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Blackhole&lt;/span&gt; &lt;span class="n"&gt;bh&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;enumMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entrySet&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="n"&gt;bh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;consume&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;hashMapIterate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Blackhole&lt;/span&gt; &lt;span class="n"&gt;bh&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hashMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entrySet&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="n"&gt;bh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;consume&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;enumSetUnion&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enumSet&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enumSet&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Benchmark&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;hashSetUnion&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My results (your numbers will vary by JVM version and hardware):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;EnumMap/EnumSet&lt;/th&gt;
&lt;th&gt;HashMap/HashSet&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Map &lt;code&gt;get&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;3.8 ns&lt;/td&gt;
&lt;td&gt;17.2 ns&lt;/td&gt;
&lt;td&gt;4.5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set &lt;code&gt;contains&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1.9 ns&lt;/td&gt;
&lt;td&gt;14.6 ns&lt;/td&gt;
&lt;td&gt;7.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Map iterate (8 keys)&lt;/td&gt;
&lt;td&gt;21 ns&lt;/td&gt;
&lt;td&gt;83 ns&lt;/td&gt;
&lt;td&gt;4.0×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set &lt;code&gt;addAll&lt;/code&gt; (union)&lt;/td&gt;
&lt;td&gt;2.8 ns&lt;/td&gt;
&lt;td&gt;91 ns&lt;/td&gt;
&lt;td&gt;32×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The union result is the extreme one: &lt;code&gt;EnumSet.addAll()&lt;/code&gt; on two&lt;br&gt;
&lt;code&gt;EnumSet&lt;/code&gt; instances is a single &lt;code&gt;|=&lt;/code&gt; instruction. &lt;code&gt;HashSet.addAll()&lt;/code&gt;&lt;br&gt;
processes all 8 elements individually. At larger enum sizes the&lt;br&gt;
ratio stays constant for &lt;code&gt;EnumSet&lt;/code&gt; (still O(1)) while &lt;code&gt;HashSet&lt;/code&gt;&lt;br&gt;
scales linearly.&lt;/p&gt;


&lt;h2&gt;
  
  
  Three Mistakes That Will Catch You Off Guard
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Mistake 1: Forgetting &lt;code&gt;EnumSet&lt;/code&gt; is mutable
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This looks like a constant but isn't&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;VIEWER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Somewhere else in the codebase:&lt;/span&gt;
&lt;span class="no"&gt;VIEWER&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DELETE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Silently succeeds. Now "VIEWER" can delete.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Wrap with &lt;code&gt;Collections.unmodifiableSet()&lt;/code&gt; for anything declared as a&lt;br&gt;
constant. Java 10+ note: &lt;code&gt;Set.of()&lt;/code&gt; gives you an immutable set but&lt;br&gt;
it's not backed by &lt;code&gt;EnumSet&lt;/code&gt;, so you lose the bit-vector performance.&lt;br&gt;
For immutable + fast: &lt;code&gt;Collections.unmodifiableSet(EnumSet.of(...))&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mistake 2: &lt;code&gt;EnumSet.copyOf&lt;/code&gt; on an empty collection
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;perms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// empty&lt;/span&gt;
&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;perms&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// IllegalArgumentException&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;EnumSet.copyOf&lt;/code&gt; needs at least one element to infer the enum type.&lt;br&gt;
Guard it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;noneOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Permission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;EnumSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;perms&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 3: Relying on ordinal() across deployments
&lt;/h3&gt;

&lt;p&gt;The whole performance story here depends on ordinals being stable&lt;br&gt;
&lt;em&gt;within a JVM session&lt;/em&gt;. They are NOT stable across deployments if&lt;br&gt;
you reorder, add to the middle, or remove enum constants.&lt;/p&gt;

&lt;p&gt;This makes ordinal-based serialization dangerous:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// You serialized Status.SHIPPED as 2&lt;/span&gt;
&lt;span class="c1"&gt;// Then someone added PROCESSING between CONFIRMED and SHIPPED&lt;/span&gt;
&lt;span class="c1"&gt;// Now 2 means PROCESSING in the new version&lt;/span&gt;
&lt;span class="c1"&gt;// Your deserialized data is silently wrong&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never use &lt;code&gt;ordinal()&lt;/code&gt; directly in application logic or serialization.&lt;br&gt;
Use the enum constant's &lt;code&gt;.name()&lt;/code&gt; for any persistence that crosses&lt;br&gt;
a deployment boundary. &lt;code&gt;EnumMap&lt;/code&gt; and &lt;code&gt;EnumSet&lt;/code&gt; are safe for&lt;br&gt;
in-memory use — they recalculate ordinals from the live enum&lt;br&gt;
class each JVM start. The risk is in your own ordinal() usage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Decision Guide
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Keys/elements all from one enum type?
│
├── Yes → Constants ≤ 64?
│         ├── Yes → Use EnumMap / EnumSet. Done.
│         └── No  → Still use them. JumboEnumSet handles &amp;gt; 64.
│                   Still faster than Hash alternatives.
│
└── No  → HashMap / HashSet as normal.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additional cases to prefer EnumMap/EnumSet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hot path: you're doing millions of lookups per second&lt;/li&gt;
&lt;li&gt;Set operations: union, intersection, difference (the O(1) story)&lt;/li&gt;
&lt;li&gt;Memory pressure: embedded systems, Android, high instance count&lt;/li&gt;
&lt;li&gt;Iteration order: you need enum declaration order for free&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cases where HashMap/HashSet is correct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Null keys required (EnumMap forbids them)&lt;/li&gt;
&lt;li&gt;Mixed key types that happen to include some enums&lt;/li&gt;
&lt;li&gt;You need &lt;code&gt;ConcurrentHashMap&lt;/code&gt; semantics (no &lt;code&gt;ConcurrentEnumMap&lt;/code&gt; exists)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Summary Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;EnumMap&lt;/th&gt;
&lt;th&gt;EnumSet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;Map with enum keys&lt;/td&gt;
&lt;td&gt;Set of enum values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal storage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Object[]&lt;/code&gt; by ordinal&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;long&lt;/code&gt; bitmask&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Null keys/elements&lt;/td&gt;
&lt;td&gt;❌ NPE&lt;/td&gt;
&lt;td&gt;❌ NPE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Null values&lt;/td&gt;
&lt;td&gt;✅ allowed&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iteration order&lt;/td&gt;
&lt;td&gt;Declaration order&lt;/td&gt;
&lt;td&gt;Declaration order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread-safe&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Available since&lt;/td&gt;
&lt;td&gt;JDK 1.5&lt;/td&gt;
&lt;td&gt;JDK 1.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;addAll&lt;/code&gt; complexity&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O(1)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vs. Hash equivalent&lt;/td&gt;
&lt;td&gt;~4–5× faster get&lt;/td&gt;
&lt;td&gt;~7–32× faster ops&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both have been in the JDK since Java 5. They are not experimental,&lt;br&gt;
not third-party, and not obscure. The reason most codebases underuse&lt;br&gt;
them is habit — &lt;code&gt;HashMap&lt;/code&gt; is what people reach for first and it works&lt;br&gt;
well enough that nobody questions it.&lt;/p&gt;

&lt;p&gt;The next time you write &lt;code&gt;new HashMap&amp;lt;&amp;gt;()&lt;/code&gt; with an enum key, pause&lt;br&gt;
for two seconds. The migration path is a one-word change:&lt;br&gt;
&lt;code&gt;HashMap&lt;/code&gt; → &lt;code&gt;EnumMap&lt;/code&gt;. Same interface. Same contract. Meaningfully&lt;br&gt;
better performance. Code that communicates intent to the next&lt;br&gt;
developer who reads it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your go-to use case for EnumMap or EnumSet? I've found the&lt;br&gt;
permission system pattern comes up constantly — curious what patterns&lt;br&gt;
others have hit.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The full version of this article with additional benchmark configurations, Spring integration patterns, and serialization deep-dive is on &lt;a href="https://thecodeforge.io/java/enummap-enumset-java/" rel="noopener noreferrer"&gt;TheCodeForge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>performance</category>
    </item>
    <item>
      <title>What 3 Years of Stack Overflow Data Tells Us About AI and Machine Learning in Development</title>
      <dc:creator>TheCodeForge</dc:creator>
      <pubDate>Mon, 09 Mar 2026 08:49:42 +0000</pubDate>
      <link>https://forem.com/thecodeforge/what-3-years-of-stack-overflow-data-tells-us-about-ai-and-machine-learning-in-development-am1</link>
      <guid>https://forem.com/thecodeforge/what-3-years-of-stack-overflow-data-tells-us-about-ai-and-machine-learning-in-development-am1</guid>
      <description>&lt;p&gt;Every year Stack Overflow surveys tens of thousands of developers worldwide. Three years of that data now tells a surprisingly nuanced story about AI and machine learning — one that's very different from the headlines.&lt;/p&gt;

&lt;p&gt;Here's what the numbers actually say.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adoption Is Climbing. Trust Is Not.
&lt;/h2&gt;

&lt;p&gt;The headline stat everyone quotes is adoption:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2023:&lt;/strong&gt; 70% of developers using or planning to use AI tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2024:&lt;/strong&gt; 76% — up 6 points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2025:&lt;/strong&gt; 84% — up another 8 points&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;By that number alone, AI adoption in software development looks like a runaway train.&lt;/p&gt;

&lt;p&gt;But look at the sentiment data running alongside it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2023:&lt;/strong&gt; 77% favorable or very favorable toward AI tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2024:&lt;/strong&gt; 72% — down 5 points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2025:&lt;/strong&gt; 60% — down another 12 points&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;More developers are using AI every year. Fewer of them feel good about it every year. That gap is the most important story in three years of this data and almost nobody is talking about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trust Problem Is Structural
&lt;/h2&gt;

&lt;p&gt;It's not that developers tried AI and had a bad experience. It's that the more they use it, the more clearly they see its limitations.&lt;/p&gt;

&lt;p&gt;In 2024, only 43% of developers said they trust the accuracy of AI output. In 2025, 87% expressed concern about accuracy and 81% had concerns about security and privacy.&lt;/p&gt;

&lt;p&gt;The most cited frustration in 2025? "AI solutions that are almost right, but not quite" — cited by 66% of developers. The second biggest? Debugging AI-generated code taking more time than writing it from scratch.&lt;/p&gt;

&lt;p&gt;This is not a beginner problem. Almost half of professional developers in 2024 said AI tools struggle with complex tasks. Trust in AI answers is so low that 75% of Stack Overflow users said they'd still ask a human rather than trust AI output.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Machine Learning Is Now a Required Skill — Not Optional
&lt;/h2&gt;

&lt;p&gt;Here's the shift that matters for anyone building a development career:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;36% of developers&lt;/strong&gt; learned to code specifically for AI in the last year&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;44% of developers&lt;/strong&gt; used AI-enabled tools to learn new coding skills in 2025, up from 37% in 2024&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;67% of developers&lt;/strong&gt; are learning to code for AI in the workplace or on personal projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python usage jumped 7 percentage points&lt;/strong&gt; from 2024 to 2025 — the survey specifically cites its role in AI, data science, and back-end development as the driver&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The message is clear: understanding how machine learning systems work is no longer a specialisation. It's becoming table stakes for any developer who wants to stay relevant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who's Actually Using What
&lt;/h2&gt;

&lt;p&gt;The LLM landscape among developers in 2025:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI GPT models:&lt;/strong&gt; 81% of developers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Sonnet:&lt;/strong&gt; 43% (used more by professional developers than learners)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini Flash:&lt;/strong&gt; 35%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AI development tools and IDEs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cursor:&lt;/strong&gt; 18% adoption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code:&lt;/strong&gt; 10%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windsurf:&lt;/strong&gt; 5%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ChatGPT had a 75% admiration rate in 2024 — meaning most developers who used it wanted to keep using it. That's a strong signal. But it also means the market is still being shaped, and alternatives are gaining ground fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Agents: Promising But Overhyped
&lt;/h2&gt;

&lt;p&gt;The 2025 survey asked directly about AI agents — autonomous AI systems that complete multi-step tasks without human intervention.&lt;/p&gt;

&lt;p&gt;The verdict is not what the hype suggests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only &lt;strong&gt;31%&lt;/strong&gt; of developers currently use AI agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;17%&lt;/strong&gt; plan to use them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;38%&lt;/strong&gt; have no plans to use them at all&lt;/li&gt;
&lt;li&gt;Only &lt;strong&gt;17%&lt;/strong&gt; of agent users say agents have improved team collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The individual productivity gains are real — 69% of agent users report increased personal productivity. But "this made me faster" and "this transformed how teams work" are very different claims. The data supports the first. Not yet the second.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for Learning Machine Learning
&lt;/h2&gt;

&lt;p&gt;Three conclusions stand out from the three-year trend:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Learning ML fundamentals is more valuable than learning specific tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tools are shifting fast — the top AI IDE in 2025 barely existed in 2024. But the underlying concepts — how models are trained, what bias-variance trade-off means, why overfitting happens — those don't change. Invest in the fundamentals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Python is the language of AI, full stop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 7-point surge in Python adoption is directly tied to AI. If you're choosing a language to learn for ML/AI work, this is an easy call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The trust gap is a career opportunity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If 66% of developers are frustrated by AI that is "almost right but not quite" — someone needs to understand these systems well enough to catch and fix those errors. That's not a job AI can do. It's a job for a developer who deeply understands how ML models work.&lt;/p&gt;

&lt;p&gt;The adoption curve is steep. The understanding curve is lagging behind. That gap is exactly where skilled developers will differentiate themselves over the next few years.&lt;/p&gt;







&lt;p&gt;&lt;em&gt;Data sourced from Stack Overflow Developer Surveys &lt;a href="https://survey.stackoverflow.co/2023/" rel="noopener noreferrer"&gt;2023&lt;/a&gt;, &lt;a href="https://survey.stackoverflow.co/2024/ai" rel="noopener noreferrer"&gt;2024&lt;/a&gt;, and &lt;a href="https://survey.stackoverflow.co/2025/ai" rel="noopener noreferrer"&gt;2025&lt;/a&gt;. If you're building ML fundamentals to navigate this landscape, &lt;a href="https://thecodeforge.io/ml-ai/" rel="noopener noreferrer"&gt;thecodeforge.io/ml-ai/&lt;/a&gt; covers the core concepts worth knowing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>The for Loop in Java — What Most Tutorials Don't Tell You</title>
      <dc:creator>TheCodeForge</dc:creator>
      <pubDate>Mon, 09 Mar 2026 07:02:25 +0000</pubDate>
      <link>https://forem.com/thecodeforge/the-for-loop-in-java-what-most-tutorials-dont-tell-you-46fl</link>
      <guid>https://forem.com/thecodeforge/the-for-loop-in-java-what-most-tutorials-dont-tell-you-46fl</guid>
      <description>&lt;p&gt;If you've been writing Java for more than a week, you've written a for loop. But there's a good chance you're using it on autopilot without fully understanding what each part is doing — or when to reach for a different loop entirely.&lt;/p&gt;

&lt;p&gt;This article breaks down the for loop properly, covers the variants Java gives you, and touches on the mistakes that even experienced developers make.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basic Structure
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10; i++) {&lt;br&gt;
    System.out.println(i);&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are three parts inside the parentheses, separated by semicolons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialisation — int i = 0 — runs once before the loop starts&lt;/li&gt;
&lt;li&gt;Condition — i &amp;lt; 10 — checked before every iteration, loop stops when false&lt;/li&gt;
&lt;li&gt;Update — i++ — runs after every iteration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This seems obvious until you realise that all three parts are optional. This is valid Java:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for (;;) {&lt;br&gt;
    // infinite loop — runs forever&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's equivalent to while(true). Understanding that all three parts are optional makes you understand what the loop is actually doing — not just following a template.&lt;/p&gt;
&lt;h2&gt;
  
  
  Iterating Over Arrays
&lt;/h2&gt;

&lt;p&gt;`&lt;br&gt;
String[] languages = {"Java", "Python", "JavaScript"};&lt;/p&gt;

&lt;p&gt;for (int i = 0; i &amp;lt; languages.length; i++) {&lt;br&gt;
    System.out.println(languages[i]);&lt;br&gt;
}`&lt;/p&gt;

&lt;p&gt;One thing developers trip over here: languages.length is a property, not a method call — no parentheses. Compare this to ArrayList where it's list.size(). Getting these mixed up is a surprisingly common bug.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Enhanced for Loop (for-each)
&lt;/h2&gt;

&lt;p&gt;Java 5 introduced the enhanced for loop, and for most iteration tasks it's cleaner:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for (String lang : languages) {&lt;br&gt;
    System.out.println(lang);&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Read this as "for each String lang in languages". No index management, no off-by-one errors.&lt;/p&gt;

&lt;p&gt;Use the enhanced for loop when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don't need the index&lt;/li&gt;
&lt;li&gt;You're just reading elements, not modifying them&lt;/li&gt;
&lt;li&gt;You're iterating over any Iterable — arrays, ArrayLists, Sets, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the traditional for loop when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need the index value&lt;/li&gt;
&lt;li&gt;You're modifying elements by position&lt;/li&gt;
&lt;li&gt;You need to iterate in reverse&lt;/li&gt;
&lt;li&gt;You need to skip elements (step by 2, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Nested for Loops
&lt;/h2&gt;

&lt;p&gt;`int[][] matrix = {&lt;br&gt;
    {1, 2, 3},&lt;br&gt;
    {4, 5, 6},&lt;br&gt;
    {7, 8, 9}&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;for (int row = 0; row &amp;lt; matrix.length; row++) {&lt;br&gt;
    for (int col = 0; col &amp;lt; matrix[row].length; col++) {&lt;br&gt;
        System.out.print(matrix[row][col] + " ");&lt;br&gt;
    }&lt;br&gt;
    System.out.println();&lt;br&gt;
}&lt;br&gt;
`&lt;br&gt;
The outer loop walks rows. The inner loop walks columns. Use row and col instead of i and j — it makes the intent obvious at a glance.&lt;/p&gt;
&lt;h2&gt;
  
  
  Variable Scope Inside the Loop
&lt;/h2&gt;

&lt;p&gt;A variable declared in the initialisation section only exists inside the loop:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
for (int i = 0; i &amp;lt; 5; i++) {&lt;br&gt;
    System.out.println(i);&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
// System.out.println(i); — won't compile, i is out of scope&lt;/p&gt;

&lt;p&gt;If you need the final value after the loop, declare it outside:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
int i;&lt;br&gt;
for (i = 0; i &amp;lt; 5; i++) {&lt;br&gt;
    System.out.println(i);&lt;br&gt;
}&lt;br&gt;
System.out.println("Final i: " + i); // prints 5&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  break and continue
&lt;/h2&gt;

&lt;p&gt;break exits the loop immediately:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10; i++) {&lt;br&gt;
    if (i == 5) break;&lt;br&gt;
    System.out.println(i); // prints 0 to 4&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;continue skips the rest of the current iteration:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10; i++) {&lt;br&gt;
    if (i % 2 == 0) continue;&lt;br&gt;
    System.out.println(i); // prints odd numbers only&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In nested loops, break only exits the innermost loop. For breaking out of multiple levels, Java supports labelled breaks:&lt;/p&gt;

&lt;p&gt;outer:&lt;br&gt;
&lt;code&gt;for (int i = 0; i &amp;lt; 5; i++) {&lt;br&gt;
    for (int j = 0; j &amp;lt; 5; j++) {&lt;br&gt;
        if (j == 2) break outer;&lt;br&gt;
        System.out.println(i + ", " + j);&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;p&gt;Off-by-one errors are the most frequent bug. The condition i &amp;lt;= 10 runs 11 times. i &amp;lt; 10 runs 10 times. For zero-indexed arrays always use i &amp;lt; array.length.&lt;/p&gt;

&lt;p&gt;Modifying a collection while iterating with a for-each loop throws ConcurrentModificationException:&lt;br&gt;
`&lt;br&gt;
List list = new ArrayList&amp;lt;&amp;gt;(Arrays.asList("a", "b", "c"));&lt;/p&gt;

&lt;p&gt;for (String s : list) {&lt;br&gt;
    if (s.equals("b")) list.remove(s); // throws exception&lt;br&gt;
}`&lt;/p&gt;

&lt;p&gt;Use an Iterator directly or iterate backwards with a traditional for loop when removing while iterating.&lt;/p&gt;
&lt;h2&gt;
  
  
  When Not to Use a for Loop
&lt;/h2&gt;

&lt;p&gt;If you're transforming or filtering a collection in modern Java, streams are often cleaner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// Traditional
List&amp;lt;Integer&amp;gt; evens = new ArrayList&amp;lt;&amp;gt;();
for (int n : numbers) {
    if (n % 2 == 0) evens.add(n);
}

// Stream equivalent
List&amp;lt;Integer&amp;gt; evens = numbers.stream()
    .filter(n -&amp;gt; n % 2 == 0)
    .collect(Collectors.toList());

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

&lt;/div&gt;



&lt;p&gt;Neither is universally better — traditional loops are easier to debug step by step, streams shine for complex pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;The for loop is one of those things that looks simple on the surface but has enough depth to trip up developers at every level. Get comfortable with all three variants — traditional, enhanced, and the edge cases around scope and modification — and you'll write cleaner, more intentional Java.&lt;/p&gt;

&lt;p&gt;For a deeper walkthrough of for &lt;a href="//thecodeforge.io/java/for-loop-java/"&gt;loops&lt;/a&gt; with more examples, is worth a read.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How Memory Actually Works in Programming (No Jargon, Just Clarity)</title>
      <dc:creator>TheCodeForge</dc:creator>
      <pubDate>Fri, 06 Mar 2026 16:10:19 +0000</pubDate>
      <link>https://forem.com/thecodeforge/how-memory-actually-works-in-programming-no-jargon-just-clarity-4eck</link>
      <guid>https://forem.com/thecodeforge/how-memory-actually-works-in-programming-no-jargon-just-clarity-4eck</guid>
      <description>&lt;p&gt;Every developer uses memory every single day. But most tutorials skip the "why" and jump straight to syntax.&lt;/p&gt;

&lt;p&gt;This post fixes that. By the end, you'll understand what's actually happening when your code runs — and why it matters for writing better software.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Warehouse Analogy
&lt;/h2&gt;

&lt;p&gt;Imagine your computer's memory as a massive warehouse with millions of numbered shelves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each shelf holds a small piece of data&lt;/li&gt;
&lt;li&gt;Each shelf has a unique address (a number)&lt;/li&gt;
&lt;li&gt;Your program is a worker who reads from and writes to those shelves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're telling the computer: &lt;em&gt;"Find an empty shelf, write the number 25 on it, and remember that shelf's address as 'age'."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's it. That's variables.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stack vs Heap — The Two Zones of the Warehouse
&lt;/h2&gt;

&lt;p&gt;Here's where most people get confused. The warehouse has &lt;strong&gt;two sections&lt;/strong&gt; with very different rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  🟧 The Stack — Fast, Organised, Temporary
&lt;/h3&gt;

&lt;p&gt;Think of the Stack like a neat pile of trays in a cafeteria.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each time you call a function, a new tray is placed on top&lt;/li&gt;
&lt;li&gt;The tray holds all the local variables for that function&lt;/li&gt;
&lt;li&gt;When the function finishes, the tray is removed instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's fast because it's organised&lt;/strong&gt; — always add/remove from the top
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// lives on the Stack&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// lives on the Stack&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" is "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// When greet() ends — name and age are GONE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Stack is self-cleaning. You don't have to do anything — memory is freed automatically when the function returns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack facts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very fast allocation and deallocation&lt;/li&gt;
&lt;li&gt;Limited size (usually 1–8MB)&lt;/li&gt;
&lt;li&gt;Stores: local variables, function calls, primitive types&lt;/li&gt;
&lt;li&gt;Lifetime: tied to the function that created them&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🟦 The Heap — Flexible, Powerful, Your Responsibility
&lt;/h3&gt;

&lt;p&gt;The Heap is the rest of the warehouse — massive, unorganised, and persistent.&lt;/p&gt;

&lt;p&gt;When you create an &lt;strong&gt;object&lt;/strong&gt;, it goes on the Heap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The reference 'person' lives on the Stack&lt;/span&gt;
&lt;span class="c1"&gt;// But the actual Person object lives on the Heap&lt;/span&gt;
&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Heap is where objects live because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They can be &lt;strong&gt;large&lt;/strong&gt; (images, lists, complex data)&lt;/li&gt;
&lt;li&gt;They need to &lt;strong&gt;outlive&lt;/strong&gt; the function that created them&lt;/li&gt;
&lt;li&gt;Multiple parts of your code may need to &lt;strong&gt;share&lt;/strong&gt; them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Heap facts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Much larger than the Stack (limited only by RAM)&lt;/li&gt;
&lt;li&gt;Slower to allocate (has to find a free block)&lt;/li&gt;
&lt;li&gt;Stores: objects, arrays, anything created with &lt;code&gt;new&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lifetime: until nothing references it anymore&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Reference Trick That Confuses Everyone
&lt;/h2&gt;

&lt;p&gt;Here's the thing that trips up almost every beginner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// What just happened?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most people think &lt;code&gt;b&lt;/code&gt; is a copy of Alice. It's not.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;b&lt;/code&gt; is a &lt;strong&gt;copy of the address&lt;/strong&gt; (reference) pointing to the same Alice on the Heap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stack:                  Heap:
┌─────────────┐         ┌──────────────────┐
│ a → [0x4A2] │────────▶│ Person("Alice")  │
│ b → [0x4A2] │────────▶│                  │
└─────────────┘         └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So when you do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints "Bob" !&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; point to the same object. Change it through one, the other sees it too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is why "pass by reference vs pass by value" matters so much in interviews.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Garbage Collection — The Automatic Cleaner
&lt;/h2&gt;

&lt;p&gt;In languages like Java, Python, and JavaScript, you don't manually free Heap memory. A &lt;strong&gt;Garbage Collector (GC)&lt;/strong&gt; does it for you.&lt;/p&gt;

&lt;p&gt;The GC periodically scans the Heap looking for objects that nothing points to anymore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="c1"&gt;// Alice is now unreachable — GC will clean her up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alice has no references. She's garbage (no offence, Alice). The GC reclaims her memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Languages with GC:&lt;/strong&gt; Java, Python, JavaScript, C#, Go&lt;br&gt;
&lt;strong&gt;Languages without GC (manual memory):&lt;/strong&gt; C, C++, Rust (ownership model)&lt;/p&gt;

&lt;p&gt;In C, forgetting to free memory causes &lt;strong&gt;memory leaks&lt;/strong&gt; — your program slowly eats up RAM until it crashes. This is why C/C++ developers have a reputation for being careful.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Does Any of This Matter?
&lt;/h2&gt;

&lt;p&gt;Understanding memory makes you a better developer in very practical ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. You'll understand NullPointerExceptions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// reference points to nothing&lt;/span&gt;
&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;     &lt;span class="c1"&gt;// CRASH — you're asking for the address of nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. You'll write faster code&lt;/strong&gt;&lt;br&gt;
Accessing Stack memory is significantly faster than Heap. Knowing this helps you make smarter decisions about data structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You'll debug memory leaks&lt;/strong&gt;&lt;br&gt;
If your app slows down over time, something is holding onto Heap objects it shouldn't be. Knowing how memory works tells you where to look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. You'll ace interviews&lt;/strong&gt;&lt;br&gt;
Stack vs Heap, pass by value vs reference, garbage collection — these come up constantly in technical interviews.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;th&gt;Heap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very fast&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Small (1-8MB)&lt;/td&gt;
&lt;td&gt;Large (GBs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stores&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Primitives, references&lt;/td&gt;
&lt;td&gt;Objects, arrays&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Managed by&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CPU automatically&lt;/td&gt;
&lt;td&gt;GC or manually&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lifetime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Function scope&lt;/td&gt;
&lt;td&gt;Until unreferenced&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Want to Go Deeper?
&lt;/h2&gt;

&lt;p&gt;If this clicked for you, here are some great next reads:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://thecodeforge.io/java/data-types-java/" rel="noopener noreferrer"&gt;Variables and Data Types explained&lt;/a&gt; — TheCodeForge&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://thecodeforge.io/java/introduction-to-java/" rel="noopener noreferrer"&gt;How Garbage Collection works in Java&lt;/a&gt; — TheCodeForge&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://thecodeforge.io/c-cpp/introduction-c-programming/" rel="noopener noreferrer"&gt;Pointers and Memory in C&lt;/a&gt; — TheCodeForge&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  One Last Thing
&lt;/h2&gt;

&lt;p&gt;Memory management is one of those topics where a 10-minute read saves you 10 hours of debugging.&lt;/p&gt;

&lt;p&gt;The next time your code crashes with a NullPointerException, a StackOverflowError, or a mysterious slowdown — you'll know exactly where to look.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this helpful? I publish plain-English programming tutorials at &lt;a href="https://thecodeforge.io" rel="noopener noreferrer"&gt;TheCodeForge.io&lt;/a&gt; — 1,057+ tutorials across Java, Python, DSA, JavaScript and more. Always free.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>programming</category>
      <category>beginners</category>
      <category>computerscience</category>
      <category>java</category>
    </item>
  </channel>
</rss>
