TreeSet
TreeSet 클래스 역시 Set 인터페이스를 구현한 클래스다. Set 인터페이스를 구현했기 때문에 데이터에 대한 중복 저장을 하지 않으며, 저장된 순서를 유지하지 않는다.
해시코드를 이용해서 내부 해시 테이블에 데이터를 저장하는 HashSet과 다르게 TreeSet은 내부에 데이터 저장을 위한 RB-Tree(Red/Black Tree) 자료구조를 가지고 있다. RB 트리는 이진탐색트리(Binary Search Tree)의 일종으로 저장된 값들이 트리 전체에 고루 저장되도록하여 비정상적으로 트리의 높이가 높아지는 현상이 없게 만든 균형트리(Balanced Tree)다.
아무튼 내부에 RB 트리를 이용해서 값을 저장하기 때문에 현재까지 저장된 값들 중 최소 값 혹은 최대 값을 출력할 수 있으며, 특정 값보다 큰 값을 빠르게 찾아낼 수 있다. 삽입과 삭제 연산에서 RB 트리의 밸런스를 맞추는 동작이 호출되어 약간의 성능 손해를 보면서, 탐색에서의 이점을 가져간 자료구조라고 할 수 있다.
TreeSet 사용법
TreeSet 생성
TreeSet<String> set1 = new TreeSet<>();// TreeSet 생성
TreeSet<String> set2 = new TreeSet<>(comparator); // 비교 메소드를 전달
TreeSet<String> set2 = new TreeSet<Integer>(otherCollection);// 다른 컬렉션에서부터 생성
TreeSet 객체를 생성할 때, 어떤 데이터를 다룰 것인지 '지네릭스(Generics)'로 선언해줘야한다. 여기서 선언된 클래스는 Comparable 객체면 좋다. Comparable 객체가 아니라면 객체의 비교에 사용할 comparator 객체를 생성자에 넣어주면 된다. comparator를 이용해서 두 객체를 비교하고, 비교 결과를 기준으로 RB 트리를 빌드해나간다.
다른 컬렉션 객체로부터 TreeSet을 생성할 수도 있다.
TreeSet 값 추가
Set 인터페이스에 정의되어 있는 add() 메소드를 이용해서 값을 추가할 수 있다.
set.add("Data1");
set.add("Data2");
set.add("Data1"); // 중복 저장 안됨 false 리턴
TreeSet에 add() 메소드를 이용해서 값을 추가할 경우 입력되는 값이 TreeSet 내부에 존재하지 않는다면 값을 추가하고 true를 리턴한다. 만약 입력된 값이 TreeSet 내부에 존재한다면 false가 리턴된다.
앞서 언급했던 것처럼 내부에서 RB 트리를 유지해야하기 때문에 새로운 값을 추가하게 되면 트리의 밸런스를 맞추는 동작이 수행되기 때문에 약간 느려질 수 있다.
TreeSet 값 삭제
TreeSet에서 값을 제거하려면 remove() 메소드 혹은 clear() 메소드를 이용하면 된다.
set.remove("Data1"); // "Data1" 제거, 존재하지 않으면 false 리턴
set.clear(); // 모든 값 제거
remove() 메소드를 이용해서 특정 값을 TreeSet에서 제거할 수 있다. 이 때, 제거하라고 입력한 값이 TreeSet에 존재하면 값을 제거하고 true가 리턴된다. 반대로 존재하지 않으면 false가 리턴된다.
TreeSet에 저장되어 있는 모든 값을 제거하려면 clear() 메소드를 호출하면 된다.
TreeSet 값 확인
set.size(); // HashSet에 저장되어 있는 데이터의 개수
set.first(); // TreeSet에 저장된 값 중 최소값
set.last(); // TreeSet에 저장된 값 중 최대값
set.higher("Data1"); // "Data1" 보다 큰 값 중에 최소값
set.lower("Data1"); // "Data1" 보다 작은 값 중에 최대값
set.contains("Data1"); // "Data1"이 HashSet에 포함되어 있는지 확인
// for 문으로 순회
for (String elem : set) {
System.out.println(elem);
}
우선 TreeSet에 저장된 값의 개수를 확인하기 위해서는 size() 메소드를 호출하면 된다.
first() 메소드를 호출할 경우 TreeSet에 저장되어 있는 값 중 최소 값을 리턴한다. last() 메소드는 반대로 TreeSet에 저장되어 있는 값 중 최대 값을 리턴한다. 내부에 RB 트리 같은 트리 구조로 데이터를 저장하기 때문에 이런 메소드의 사용이 가능하다.
higher() 메소드는 인자로 받은 값 보다 큰 값들 중에 가장 작은 값이 출력된다. 즉, 인자로 받은 값 다음 값을 출력해준다. lower() 메소드는 인자로 받은 값보다 작은 값들 중에 가장 큰 값이 출력된다.
contains() 메소드는 TreeSet에 특정 값이 저장되어 있는지 확인할 때 사용한다.
다른 컬렉션과 마찬가지로 for each 구문을 이용해서 TreeSet에 저장된 데이터를 순회할 수 있다.
댓글