### 集合
Sets 是一個包含不重復元素的集合。當我們要求集合里面的元素不可以重復,并且我們不要求集合里面的元素保持它們添加時候的順序,那么sets是比較適合的。 Clojure 支持兩種不同的set: 排序的和不排序的。如果添加到set里面的元素相互之間不能比較大小,那么一個 `ClassCastException` 異常會被拋出來。下面是一些創建set的方法:
```
(def stooges (hash-set "Moe" "Larry" "Curly")) ; not sorted
(def stooges #{"Moe" "Larry" "Curly"}) ; same as previous
(def stooges (sorted-set "Moe" "Larry" "Curly"))
```
`contains?` 函數可以操作sets和maps. 當操作set的時候, 它返回給定的set是否包含某個元素。這比在list和vector上面使用的 `some函數就簡單多了` . 看例子:
```
(contains? stooges "Moe") ; -> true
(contains? stooges "Mark") ; -> false
```
Sets 可以被當作它里面的元素的函數來使用. 當以這種方式來用的時候,返回值要么是這個元素,要么是nil. 這個比起contains?函數來說更簡潔. 比如:
```
(stooges "Moe") ; -> "Moe"
(stooges "Mark") ; -> nil
(println (if (stooges person) "stooge" "regular person"))
```
在介紹list的時候提到的函數 `conj` 和 `into` 對于set也同樣適用. 只是元素的順序只有對sorted-set才有定義.
`disj` 函數通過去掉給定的set里面的一些元素來創建一個新的set. 看例子:
```
(def more-stooges (conj stooges "Shemp")) ; -> #{"Moe" "Larry" "Curly" "Shemp"}
(def less-stooges (disj more-stooges "Curly")) ; -> #{"Moe" "Larry" "Shemp"}
```
你也可以看看 `clojure.set` 名字空間里面的一些函數: `difference` , `index` , `intersection` , `join` , `map-invert` , `project` , `rename` , `rename-keys` , `select` 和 `union` . 其中有些函數的操作的對象是map而不是set。