Browse Learn Clojure Foundations as a Java Developer

Comparing Mutable and Immutable Data Structures

Compare Java's mutable collection defaults with Clojure's persistent immutable collections, including aliasing risks, update semantics, and realistic JVM performance trade-offs.

Java collections are usually mutable: you create a HashMap, then add/remove/modify entries. Clojure collections are persistent and immutable: you produce a new map with the change applied.

The real difference is not syntax

  • Mutable structures optimize for in-place updates, but make shared state and reasoning harder.
  • Persistent structures optimize for safe sharing and easy reasoning, using structural sharing to keep updates practical.

What to watch for as a Java developer

  • In Clojure, “copying” is often cheap because the new value reuses structure.
  • You design APIs around returning new values rather than modifying arguments.
  • When interoping with Java, you must be explicit about where mutation is allowed.

This section helps you build intuition about the performance model so immutability feels like a tool, not a constraint.

In this section

  • Mutable Data Structures in Java
    Review the Java collection habits Clojure is reacting against: in-place updates, shared aliases, defensive copying, and synchronization pressure.
  • Immutable Data Structures in Clojure
    Contrast Java's collection mutation model with Clojure's persistent maps, vectors, sets, and lists.
  • Collection Performance Trade-Offs
    Adopt a realistic performance model for persistent collections: measure first, use transients or Java structures only where the data proves it matters.
Revised on Saturday, May 23, 2026