17.7.2 HashSet
HashSet
을 HashMap
으로 생각해보면 우리는 키에 대해서만 신경쓰면 된다.(HashSet<T>
는 사실상 HashMap<T, ()>
을 포장한 것)
"요지가 뭐야?"하고 물을 수 있다. "난 그냥 Vect
에 보관할래."
HashSet
의 특별한 기능은 중복 요소가 없다고 보장한다는 점이다. 이는 모든 set류의 콜렉션이 보장하는 내용이며 HashSet
은 하나의 구현체이다. (BtreeSet
을 봐라)
HashSet
에 이미 있는 값을 삽입하면 (즉 새 값이 기존 값과 같고 둘 모두 같은 해쉬 값을 갖음) 새 값이 이전 값을 대체한다.
이것은 무언가가 하나 이상이 존재하기 원하지 않을 때나 이미 무언가를 가지고 있음을 알고 싶을 때 유용하다.
그러나 set류는 그 이상을 할 수 있다.
Set류는 4개의 기본 연산을 가진다(다음 호출 모두가 반복자를 반환한다):
union
: 두 sets의 모든 고유 요소들을 가져온다.difference
: 첫 set에는 있지만 두 번째에는 없는 모든 요소를 가져온다.intersection
: 두 set에 모두 존재하는 요소들을 가져온다.symmetric_difference
: 단 한 set에만 존재하는 모든 요소를 가져온다.
다음의 예제를 통해 이들을 모두 시험해보자.
use std::collections::HashSet; fn main() { let mut a: HashSet<i32> = vec!(1i32, 2, 3).into_iter().collect(); let mut b: HashSet<i32> = vec!(2i32, 3, 4).into_iter().collect(); assert!(a.insert(4)); assert!(a.contains(&4)); // `HashSet::insert()`는 이미 값이 있을 시에 false를 반환한다. assert!(b.insert(4), "Value 4 is already in set B!"); // FIXME ^ 해당 라인을 주석 처리해보세요. b.insert(5); // 만약 콜렉션의 요소 타입이 `Debug`를 구현하면 // 콜렉션도 `Debug`를 구현한다. // 일반적으로 요소를 `[elem1, elem2, ...]`형식으로 출력한다. println!("A: {:?}", a); println!("B: {:?}", b); // [1, 2, 3, 4, 5]를 임의의 순서로 출력한다. println!("Union: {:?}", a.union(&b).collect::<Vec<&i32>>()); // 이것은 [1]을 출력해야 한다. println!("Difference: {:?}", a.difference(&b).collect::<Vec<&i32>>()); // [2, 3, 4] 이 임의의 순서로 출력된다. println!("Intersection: {:?}", a.intersection(&b).collect::<Vec<&i32>>()); // [1, 5] 출력 println!("Symmetric Difference: {:?}", a.symmetric_difference(&b).collect::<Vec<&i32>>()); }
(Examples adapted from the documentation.)