Skip to content

Clojure Data Structures Guide — Lists, Vectors, Maps, and Sets

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Clojure Data Structures Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Clojure persistent data structures are immutable with O(log32 n) access and modification through structural sharing -- lists for sequential access, vectors for indexed access, maps for key-value lookup, and sets for uniqueness testing.

Lists

;; Lists are linked lists (sequential access)
'(1 2 3 4 5)
(list 1 2 3 4 5)

;; cons: prepend
(cons 1 '(2 3))   ;; (1 2 3)

;; conj: prepend for lists
(conj '(2 3) 1)   ;; (1 2 3)

;; first, rest, last
(first '(1 2 3))  ;; 1
(rest '(1 2 3))   ;; (2 3)
(last '(1 2 3))   ;; 3

Vectors

;; Vectors are indexed (O(log32 n) access)
[1 2 3 4 5]
(vector 1 2 3 4 5)

;; conj: append for vectors
(conj [1 2] 3)    ;; [1 2 3]

;; Indexed access
(get [10 20 30] 1)  ;; 20
([10 20 30] 1)      ;; 20 (vector as function)

;; Subvector
(subvec [1 2 3 4 5] 1 3)  ;; [2 3]

;; Associative operations
(assoc [1 2 3] 1 99)  ;; [1 99 3]

Maps

;; Maps are key-value dictionaries
{:name "Alice" :age 30 :city "NYC"}

;; Access
(get {:a 1 :b 2} :a)   ;; 1
({:a 1 :b 2} :a)       ;; 1
(:a {:a 1 :b 2})       ;; 1 (keyword as function)

;; Association
(assoc {:a 1} :b 2)   ;; {:a 1, :b 2}

;; Dissociation
(dissoc {:a 1 :b 2} :a)  ;; {:b 2}

;; Merge
(merge {:a 1} {:b 2})    ;; {:a 1, :b 2}

;; Nested access
(get-in {:a {:b 2}} [:a :b])  ;; 2

Sets

;; Sets are collections of unique elements
#{1 2 3 4 5}
(hash-set 1 2 3 2 1)  ;; #{1 2 3}

;; Membership
(get #{1 2 3} 2)  ;; 2
(contains? #{1 2} 3)  ;; false

;; Operations
(clojure.set/union #{1 2} #{2 3})      ;; #{1 2 3}
(clojure.set/intersection #{1 2} #{2 3})  ;; #{2}
(clojure.set/difference #{1 2 3} #{2})    ;; #{1 3}

;; Add/remove
(conj #{1 2} 3)   ;; #{1 2 3}
(disj #{1 2} 1)   ;; #{2}

Common Mistakes

1. Using lists for indexed access

Lists require O(n) access. Use vectors when you need (nth coll index).

2. Mixing lists and vectors with conj

(conj '(1 2) 3) gives (3 1 2) (prepends). (conj [1 2] 3) gives [1 2 3] (appends).

3. Forgetting maps are functions

Keywords are functions: (:key map) is equivalent to (get map :key). Maps are also functions of their keys.

Practice Questions

1. What is the difference between a list and a vector? Lists are linked lists (O(n) access). Vectors are indexed (O(log32 n) access). conj prepends to lists, appends to vectors.

2. How do you access a nested map value? (get-in map [:key1 :key2]) or the threading macros: (-> map :key1 :key2).

3. How do you check if a value is in a set? (contains? set value) or (get set value) returns the value or nil.

FAQ

{{< faq question="Are Clojure data structures mutable?" >}} No, all core data structures are immutable. Operations return new versions. This ensures Thread Safety. {{< /faq >}}

{{< faq question="What is structural sharing?" >}} New versions share most of the structure with the old version. Only the changed path is new. This makes immutability efficient. {{< /faq >}}

{{< faq question="How do I update a value in a nested map?" >}} (assoc-in map [:a :b :c] new-value) or (update-in map [:a :b] fn). {{< /faq >}}

What's Next

Now learn about functions in Clojure.

Topic Description Link
Functions Defining and using functions {{< ref "05-functions" >}}
Sequences Sequence abstraction {{< ref "06-sequences" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro