Hash Tables

Options: :size, :rehash-size, and (SBCL) :synchronized t for thread-safe tables or :weakness :key for weak tables.

(defparameter *phone* (make-hash-table :test 'equal))   ; tests: eq, eql (default), equal, equalp
(setf (gethash "ana" *phone*) "555-1234")
(setf (gethash "bo" *phone*) "555-9876")
(gethash "ana" *phone*)                    ; "555-1234", T (value and found-p)
(gethash "zed" *phone*)                    ; NIL, NIL
(gethash "zed" *phone* "unknown")          ; "unknown", NIL (default)
(remhash "bo" *phone*)
(hash-table-count *phone*)                 ; 1
(clrhash *phone*)

(maphash (lambda (k v) (format t "~a => ~a~%" k v)) *phone*)
(loop for k being the hash-keys of *phone* using (hash-value v)
      collect (cons k v))
(with-hash-table-iterator (next *phone*)
  (loop (multiple-value-bind (more k v) (next)
          (unless more (return))
          (print (list k v)))))

;; Counting with incf on gethash (missing keys start at the default 0)
(defun word-counts (words)
  (let ((counts (make-hash-table :test 'equal)))
    (dolist (w words counts)
      (incf (gethash w counts 0)))))
(alexandria:hash-table-alist (word-counts '("a" "b" "a")))   ; (("b" . 1) ("a" . 2)) (order unspecified)

;; Distinguishing "stored NIL" from "missing"
(multiple-value-bind (value found) (gethash :key (make-ha
…