Browse Learn Clojure Foundations as a Java Developer

Vectors in Clojure

Use Clojure vectors as the default ordered collection for indexed, immutable data, with practical guidance on conj, assoc, subvec, sequence functions, and Java ArrayList comparisons.

Vectors are the default ordered collection for most Clojure application data. If a Java engineer reaches for ArrayList, the first Clojure collection to consider is usually a vector.

Vectors are immutable, persistent, ordered, and indexed. Updating a vector returns a new vector that shares structure with the old one.

Core Operations

 1(def numbers [10 20 30])
 2
 3(get numbers 1)
 4;; => 20
 5
 6(nth numbers 1)
 7;; => 20
 8
 9(conj numbers 40)
10;; => [10 20 30 40]
11
12(assoc numbers 1 25)
13;; => [10 25 30]
14
15numbers
16;; => [10 20 30]

The last expression matters: numbers did not change.

Vector Operations Compared With Java

Java ArrayList habit Clojure vector form Difference
list.get(i) (get v i) or (nth v i) Returns a value without mutation
list.add(x) (conj v x) Returns a new vector with x at the end
list.set(i, x) (assoc v i x) Returns a new vector
list.subList(a, b) (subvec v a b) Returns a vector view-like value
Loop and append to new list mapv, filterv pattern with into [] Expresses result construction directly

Vectors provide efficient indexed access and efficient end appends in practice. Internally they are persistent tree structures, not resizable arrays, so think “immutable indexed value” rather than “array with a bigger capacity.”

get vs nth vs Function Call

Vectors can be used as functions of their index:

1([10 20 30] 1)
2;; => 20

That is legal, but often less readable than get or nth.

Form Missing index behavior Good use
(get v i) Returns nil or a default Safe lookup
(get v i default) Returns default Safe lookup with fallback
(nth v i) Throws when out of range Assertive positional access
(v i) Throws when out of range Compact, but use sparingly

Example:

1(get [10 20 30] 9 :missing)
2;; => :missing

Building New Vectors

Use conj when adding one or more values:

1(conj [1 2] 3 4)
2;; => [1 2 3 4]

Use into when adding many values from another collection:

1(into [1 2] [3 4 5])
2;; => [1 2 3 4 5]

Use mapv when the result should be a vector:

1(mapv #(* % %) [1 2 3])
2;; => [1 4 9]

Plain map returns a lazy sequence:

1(map #(* % %) [1 2 3])
2;; => (1 4 9)

That is useful when you want laziness, but choose mapv, vec, or into [] when the caller expects a vector.

Updating Values

assoc replaces by index:

1(assoc [:draft :submitted :paid] 1 :reviewed)
2;; => [:draft :reviewed :paid]

update reads the existing value and applies a function:

1(update [10 20 30] 1 inc)
2;; => [10 21 30]

This is the vector equivalent of “read, transform, write back,” but without mutating the original vector.

Choosing Vectors

Use a vector when… Consider another collection when…
Order matters Membership is the main operation
Index matters Keys are domain labels
You need a stable result collection You need code-as-data lists
You append at the end You repeatedly add/remove at the front

Practice

  1. Rewrite a Java ArrayList loop that builds a result list using mapv.
  2. Compare (conj [1 2 3] 4) with (conj '(1 2 3) 4).
  3. Use update to increment the second value in [10 20 30].
  4. Decide whether (get v i) or (nth v i) is better when the index may be missing.

Key Takeaways

  • Vectors are the normal ordered collection for Clojure application data.
  • conj adds to the end of a vector.
  • assoc and update return new vectors.
  • Use mapv, into [], or vec when you need a concrete vector result.
  • Do not import Java’s mutable ArrayList habits into Clojure core logic.

Quiz: Vectors in Clojure

### Where does `conj` add an element to a vector? - [x] The end. - [ ] The front. - [ ] A random location. - [ ] Only index 0. > **Explanation:** `conj` adds to the efficient end of the collection. For vectors, that is the end. ### What does `assoc` do to a vector? - [x] Returns a new vector with a value replaced at an index. - [ ] Mutates the original vector. - [ ] Sorts the vector. - [ ] Converts the vector to a set. > **Explanation:** Clojure vector updates return new values and leave the original vector unchanged. ### Which form returns a vector after mapping? - [x] `mapv` - [ ] `map` - [ ] `filter` - [ ] `seq` > **Explanation:** `mapv` eagerly returns a vector. `map` returns a lazy sequence. ### Which lookup form supports a default value? - [x] `get` - [ ] `def` - [ ] `conj` - [ ] `subvec` > **Explanation:** `(get v i default)` returns the default when the index is missing. ### True or False: Vectors are mutable resizable arrays. - [ ] True - [x] False > **Explanation:** Vectors are immutable persistent indexed collections, not mutable arrays.
Revised on Saturday, May 23, 2026