▶ HashSet
Set인터페이스에서 지원하는 구현 클래스. 그래서 Set 특징을 그대로 상속받음.
Set은 중복 허용하지 않고, 하나의 null 값만 저장 가능. 또한 순서 없이 Key로만 데이터를 저장함.
Set의 가장 큰 장점은 중복을 자동으로 제거해 줌.
Set은 비선형 구조이기 때문에 순서가 없고, 인덱스도 당연히 존재하지 않음.
따라서 값을 추가하거나 삭제할 때는 그 값이 Set 내부에 있는지 검색 한 뒤, 추가나 삭제를 해야 하므로 속도가 List 구조에 비해 느림.
Set 인터페이스를 구현하는 클래스는 HashSet, TreeSet 등이 있음.
HashSet은 중복 제거해야 할 때, 값이 존재하는지 빠르게 확인해야 할 때(contains), 정렬이 피요 없는 데이터 집합일 때 사용하면 좋음.
● HashSet 생성 ●
// 타입 지정 가능
HashSet<String> animals1 = new HashSet<String>();
// 타입 생략하여 사용 가능 → 빈 HashSet 생성 시 사용
HashSet<String> animals2 = new HashSet<>();
// 초기 용량(Capacity) 설정
HashSet<String> animals3 = new HashSet<>(10);
// animal의 모든 값을 가진 HashSet 생성
HashSet<String> animal4 = new HashSet<>(animals1);
// 초기값 지정 가능
HashSet<String> animal5 = new HashSet<>(Arrays.asList("tiger", "lion", "fox"));
● 주요 특징 ●
- 중복 허용 안 함 : 같은 값은 한 번만 저장 (값의 존재 유무 파악할 때 사용 가능)
- 순서 보장 안함 : 입력 순서와 출력 순서가 다를 수 있음
- null 허용함 : null 값을 1개 저장 가능
- 빠른 탐색 : 내부적으로 HashMap 기반으로 동작해 탐색, 삽입, 삭제가 빠름 (평균 O(1))
● 내부 동작 ●
내부적으로는 HashMap 사용해 데이터를 저장함.
값이 들어올 때 hashCode() 값을 계산해서 저장 위치 결정함.
값이 많아져도 빠르게 검색, 삽입, 삭제가 가능한 것임.
● 주요 메서드 ●
add(E e) : 요소 추가
remove(Object o) : 요소 제거
contains(Object o) : 해당 요소가 있는지 확인
size() : 저장된 요소 개수
isEmpty() : 비어있는지 확인
clear() : 모든 요소 제거
● 예시01 ●
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<String> fruits = new HashSet<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("apple"); // 중복 무시됨.
System.out.println(fruits); // [banana, apple] 순서 보장되지 않음
System.out.println(fruits.contains("banana")); // true
fruits.remove("banana");
System.out.println(fruits.contains("banana")); // false
}
}
실행결과
[banana, apple]
true
false
● 예시02 ●
import java.util.*;
public class Main {
public static void main(String[] args) {
HashSet<Integer> num = new HashSet<>();
num.add(1);
num.add(null);
num.add(1);
System.out.println(num); // [null, 1] 순서 보장하지 않음
System.out.println("num 사이즈 : " + num.size()); // 2
System.out.println("1을 포함하나요? " + num.contains(1)); // true
System.out.println("2를 포함하나요? " + num.contains(2)); // false
num.remove(1);
System.out.println("1을 포함하나요? " + num.contains(1)); // false
num.clear();
System.out.println(num); // []
num.add(1);
num.add(2);
num.add(3);
System.out.println(num.toString()); // [1, 2, 3]
Iterator iter = num.iterator();
while(iter.hasNext()) {
System.out.print(iter.next() + " "); // 1 2 3
}
System.out.println();
// 자바 Set List로 변환하여 정렬
ArrayList<Integer> list = new ArrayList<>(num); // num을 ArrayList로 변경
Collections.sort(list, ((o1, o2) -> o2 - o1)); // 내림차순 정렬
System.out.println(list.toString()); // [3, 2, 1]
Collections.sort(list, ((o1, o2) -> o1 - o2)); // 오름차순 정렬
System.out.println(list.toString()); // [1, 2, 3]
}
}
실행결과
[null, 1]
num 사이즈 : 2
1을 포함하나요? true
2를 포함하나요? false
1을 포함하나요? false
[]
[1, 2, 3]
1 2 3
[3, 2, 1]
[1, 2, 3]
▶ TreeSet
Java의 java.util 패키지에 포함된 클래스이고, Set 인터페이스를 구현하면서 내부적으로는 Red-Black Tree(이진 균형 트리) 기반으로 작동함.
데이터를 자동 정렬하면서 중복 제거하고 싶을 때나 범위 검색이 필요할 때 사용하면 좋음.HashSet보다 느리지만 정렬된 결과를 제공함.
● TreeSet 생성 ●
// 타입 지정 가능
TreeSet<Integer> num1 = new TreeSet<Integer>();
// 타입 생략하여 사용 가능 → 빈 HashSet 생성 시 사용
TreeSet<Integer> num2 = new TreeSet<>();
// 초기값 지정 가능
TreeSet<Integer> num3 = new TreeSet<>(Arrays.asList(1, 2, 3));
● 주요 특징 ●
- 중복 허용 안 함 : Set 계열이라 중복된 값은 저장되지 않음
- 자동 정렬 됨 : 값이 오름차순(기본)으로 정렬됨
- 정렬 기준 변경 가능 : Comparator를 사용하면 정렬 기준 변경 가능
- 탐색, 삭제 성능 : 평균 O(log N), 트리기반이기 때문
- null 저장 불가 : null은 저장할 수 없음 → NullPointerException 발생
● 주요 메서드 ●
add(E e) : 요소 추가
remove(E e) : 요소 제거
contains(E e) : 포함 여부 확인
first() / last() : 가장 작은 / 큰 값 반환
higher(E e) : 주어진 값보다 큰 값 중 가장 작은 값
lower(E e) : 주어진 값보다 작은 값 중 가장 큰 값
● 예시01 ●
import java.util.*;
public class Main {
public static void main(String[] args) {
TreeSet<Integer> scores = new TreeSet<>();
scores.add(50);
scores.add(20);
scores.add(70);
scores.add(20); // 중복 무시됨
System.out.println(scores); // [20, 50, 70] → 자동 오름차순
TreeSet<String> names = new TreeSet<>(Comparator.reverseOrder());
names.add("banana");
names.add("apple");
names.add("cherry");
System.out.println(names); // [cherry, banana, apple] → 내림차순
}
}
실행결과
[20, 50, 70]
[cherry, banana, apple]
● 예시02 ●
import java.util.*;
public class Main {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(5);
ts.add(3);
ts.add(9);
ts.add(7);
System.out.println(ts); // [3, 5, 7, 9] 자동 오름차순
ts.remove(3);
System.out.println(ts); // [5, 7, 9]
ts.clear(); // 전체 삭제
System.out.println(ts); // []
ts.add(1);
ts.add(5);
//ts.add(null);
System.out.println(ts);
System.out.println("ts 사이즈 : " + ts.size()); // 2
System.out.println("1을 포함하나요? " + ts.contains(1)); // true
System.out.println("2를 포함하나요? " + ts.contains(2)); // false
ts.add(3);
ts.add(9);
System.out.println(ts.first()); // 1
System.out.println(ts.last()); // 9
for (Integer t : ts) {
System.out.print(t + " "); // 1 3 5 9
}
System.out.println();
Iterator iter = ts.iterator();
while(iter.hasNext()) {
System.out.print(iter.next() + " "); // 1 3 5 9
}
System.out.println();
// 내림차순
TreeSet<Integer> nums = new TreeSet<>(Comparator.reverseOrder());
nums.add(8);
nums.add(4);
nums.add(9);
System.out.println(nums); // [9 8 4]
Iterator iterator = nums.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next()+ " "); // 9 8 4
}
}
}
실행결과
[3, 5, 7, 9]
[5, 7, 9]
[]
[1, 5]
ts 사이즈 : 2
1을 포함하나요? true
2를 포함하나요? false
1
9
1 3 5 9
1 3 5 9
[9, 8, 4]
9 8 4
null은 허용하지 않음.
TreeSet은 내부적으로 비교(compareTo or compare)를 이용해서 값을 정렬하기 때문에
null은 비교 불가하므로 NullPointerException이 터짐.
Iterator iter = ts.iteraor();에서
iterator() 메서드는 컬렉션에 대한 반복자(Iterator)를 반환함.
이 반복자를 통해 컬렉션의 요소들을 하나씩 꺼낼 수 있음.
while(iter.hasNext())에서
hasNext()는 다음에 읽을 요소가 있는지 확인하는 메서드.
true면 다음 요소가 있고, false면 더 이상 없음.
System.out.print(iter.next() + " ");에서
next()는 현재 위치의 값을 반환하고, 포인터를 다음 위치로 이동시킴.
그래서 출력하고 나면 다음 값을 준비함.
[출처]
https://velog.io/@acacia__u/hashSet
[Java] HashSet의 개념과 사용법 정리
Set 이란? Set 인터페이스 구현 클래스 객체를 중복해서 저장할 수 없으며, 하나의 null 값만 저장할 수 있다. 중복을 자동으로 제거해준다. Set은 비선형 구조이기 때문에 '순서'의 개념과 '인덱스'
velog.io
[Java] 트리셋(TreeSet) 자료구조 정리
TreeSet은 Set 인터페이스를 구현한 클래스로써 객체를 중복해서 저장할 수 없고 저장 순서가 유지되지 않는다는 Set의 성질을 그대로 가지고 있다.
velog.io
'알고리즘 > 공부의흔적' 카테고리의 다른 글
[공부의흔적]_Buffer (1) | 2025.04.19 |
---|---|
[공부의 흔적]_자바 기본 입출력_System.in.read(); (1) | 2024.12.05 |