
Collection 인터페이스와 AbstractSet 클래스를 extends 하는 Set 인터페이스를
Implements하는 클래스이다.
요소를 해시함수를 이용해 해시코드로 변환해 저장한다. 따라서 순서를 보장하지 않는다. 순서를 보장하려면 HashSet과 거의 같지만 순서를 보장하는TreeSet을 이용하자.
해시코드를 이용하기 때문인지?? 값의 중복을 허용하지 않는다.
import java.util.*;
class DemoHashSet {
public static void main(String args[]) {
HashSet<String> alphabets = new HashSet<String>();
}
}
alphabets.add("a"); //"a"를 더한다.
alphabets.remove("a"); //"a"를 삭제한다.
alphabets.clear(); // 모든 값을 삭제. set을 비운다.
alphabets.size(); // set의 크기를 가져온다. 삽입되어 있는 요소의 수.
alphabets.contains("a"); // "a"가 있는지 확인. 있으면 true를 반환.
alphabets.isEmpty();; // set이 비었는지 확인. 비었으면 true 반환.
여기서 뭔가 이상함이 느껴지지 않는가??
다른 컬랙션 처럼 get() 메서드 등 인덱스를 활용해서 값을 가져오는 메서드가 없다.
이유는 당연히 순서가 없기 때문에 index를 활용할 수 없기 때문이다.
그러면 hashSet에서는 값을 가져올 수 없는 것일까??
대표적으로 for each문을 사용할 수 있겠으나 다른 방법도 알아보자.
class DemoHashSet {
public static void main(String args[]) {
HashSet<String> alphabets = new HashSet<String>();
alphabets.add("a");
alphabets.add("b");
alphabets.add("c");
for(String s : alphabets){
System.out.println(s);
}
}
}
반복자(iterator)는 객체 지향적 프로그래밍에서 배열이나 해시셋등 그와 유사한 자료구조의 내부요소를 순회하는 객체다.
컬랙션에서 사용할 수 있는 인터페이스이다.
장점은 컬랙션 프레임워크별로 메서드를 다 몰라도
iterator 메서드 3개만 알면 반복을 돌 수 있다는 것이다.
단점은 객체를 만들어 사용하기에 느리다는 것이다.
방법은 다음과 같다.
먼저 iterator()를 사용해 iterator 객체를 생성해준다.
Iterator<String> iter = alphabets.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
}
hasNext()는 다음 요소가 있는지 판별한다.
next()는 다음 요소 값을 가져온다.
remove()는 가져온 요소를 삭제한다.
Iterator는 컬랙션 자체를 수정이 가능하다는 것이다.
정말 간단한 예로 위에서 작성한 코드에서 어떤 요소를 제거한다고 할때,
public static void main(String args[]) {
HashSet<String> alphabets = new HashSet<String>();
alphabets.add("a");
alphabets.add("b");
alphabets.add("c");
for(String s : alphabets){
if(s.equals("b")){
alphabets.remove("b");
}
}
}
ConcurrentModificationException 에러가 발생한다.
alphabets의 배열의 길이만큼 돌아야하는데 하나가 삭제되었으니 배열의 길이가 달라졌기 때문이다.
public static void main(String args[]) {
HashSet<String> alphabets = new HashSet<String>();
alphabets.add("a");
alphabets.add("b");
alphabets.add("c");
Iterator<String> iter = alphabets.iterator();
while(iter.hasNext()){
if(iter.next().equals("b")){
iter.remove();
}
}
}
이런 경우에 Iterator를 사용하여 삭제가 가능하다.
++ 다른 방법으로는 for문을 도는데 끝에서부터 반대로 순회하면서 삭제하는 방법이 있다.