Browse Clojure Foundations for Java Developers

Comparing Mutable and Immutable Data Structures

How persistent collections differ from Java's mutable defaults (and why performance is still OK).

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.
  • Performance Considerations
    Adopt a realistic performance model for persistent collections: measure first, use transients or Java structures only where the data proves it matters.
Revised on Friday, April 24, 2026