개요
안녕하세요. 빈코입니다! 오늘은 이전 포스팅에서 다룬 HashMap의 기본개념 및 시간복잡도에 이어서 HashSet을 사용하는 방법과 HashSet이 가지는 특징들에 대해 포스팅하려 합니다. 그럼 HashSet의 기본개념부터 알아볼까요?
기본 개념📙
HashSet을 알아보기 앞서 Set의 기본개념은 객체를 중복해서 저장할 수 없는 특징을 가지고 있습니다. 그래서 대부분 중복되는 값이 여러 번 추가될 수 있는 로직에서 많이 쓰이곤 합니다. Set은 저장 순서가 유지되지 않는 특징이 있는데, 만약 저장 순서도 유지하고 싶을 때는 LinkedHashSet 클래스를 사용하면 됩니다.
Set을 이용한 대표적인 클래스는 HashSet과 TreeSet이 있는데 HashSet은 앞서 말한것처럼 저장 순서가 유지되지 않고 TreeSet은 자동정렬을 지원해 주는 차이가 있습니다.
조금 더 깊게 들어가면 HashSet은 내부적으로 해시 테이블을 사용하기 때문에 빠른 조회 속도를 가집니다. 해시 테이블의 시간복잡도는 O(1)을 제공합니다. 조회/삽입/삭제에서 빠른 성능을 자랑합니다.
하지만, TreeSet은 이진 검색 트리(레드-블랙 트리)를 기반으로 구현되어, 요소를 저장할 때 정렬된 상태로 유지되는 장점은 있지만 조회속도는 HashSet에 비해 상대적으로 느릴 수 있습니다. 이진 검색 트리에서 조회 연산은 O(log n)의 시간복잡도를 가집니다.
결론적으로 HashSet은 조회 속도가 빠르고 중복 요소를 허용하지 않는 집합을 필요로 할 때 사용하고, TreeSet은 정렬된 상태로 요소를 관리해야 할 때 사용하면 좋습니다😁
사용법📘
HashSet의 사용법은 HashSet 객체 생성, 요소 추가, 요소 조회, 요소 제거, HashSet 크기 확인, HashSet 초기화, 비어 있는 HashSet인지 체크, 순회 및 요소 접근, 예외 처리에 대해 알아보려고 합니다.
HashSet 객체 생성
HashSet<String> hashSet = new HashSet<>(); // 기본 객체 생성방법
HashSet<String> hashSet2 = new HashSet<>(hashSet); // 첫번째 hashSet 추가
HashSet<String> hashSet3 = new HashSet<>(10, 0.07f); // 특정 용량 지정 가능
HashSet을 기본으로 생성했을때는 initial capacity(16), load factor(0.75)의 값을 가진 HashSet이 생성됩니다. Set은 값이 추가될 때마다 버킷을 두배로 확장하는 특징이 있기 때문에, 해당 데이터가 대용량이라면 과부하가 걸릴 확률이 높습니다. 만약 초기에 저장할 데이터의 개수를 미리 알고 있다면 Set의 초기 용량을 지정해 주는 것이 좋습니다.
HashSet 요소 추가
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
HashSet에 요소를 추가할 때는 'add()' 메서드를 사용하면 됩니다. 만약 입력되는 요소가 HashSet 내부에 존재하지 않다면 HashSet에 추가하고, 이미 존재하고 있다면 false를 반환합니다.
HashSet 요소 조회
for (String fruit : hashSet) {
System.out.println(fruit);
}
if (hashSet.contains("banana")) {
System.out.println("banana 존재하지 않는다");
}
HashSet의 모든 요소를 조회하려면 반복문을 사용하면 됩니다. 특정 요소가 존재하는지의 여부는 HashSet에서 제공하는 'contains()' 메서드를 이용하면 됩니다. 특정 요소가 HashSet의 존재한다면 true, 그렇지 않다면 false를 반환합니다.
HashSet 요소 제거
hashSet.remove("orange");
HashSet에서 요소를 제거할 때는 'remove()' 메서드를 사용합니다. HashSet에 요소가 존재한다면 그 값을 삭제 후 true 를 반환하고, 존재하지 않다면 false를 반환합니다.
HashSet 크기 확인
System.out.println("Size of HashSet: " + hashSet.size());
HashSet의 크기를 구하려면 'size()' 메서드를 사용합니다.
HashSet 초기화
hashSet.clear();
HashSet의 안에 있는 모든 요소를 제거하려면 'clear()' 메서드를 사용합니다.
HashSet 비어있는지 체크
if (hashSet.isEmpty()) {
System.out.println("HashSet is empty");
}
HashSet이 비어 있는지 여부를 체크하려면 'isEmpty()' 메서드를 사용합니다. 만약 HashSet이 비어있다면 true를 반환하고, 비어있지 않다면 false를 반환합니다.
HashSet 순회 및 요소 접근
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
실무에서 가장 많이 사용되는 방법입니다. HashSet의 Iterator 객체를 생성하기 위해 'iterator()' 메서드를 사용하고, Iterator의 다음 요소가 있는지 확인하기 위해 'hasNext()' 메서드를 사용하여 값이 있을 경우 while문을 통해 다음 요소에 접근합니다.
HashSet 순회 및 요소 삭제
while (iterator.hasNext()) {
String element = iterator.next();
if (element.equals("banana")) {
iterator.remove(); // 현재 요소를 제거
}
}
위에서 만든 Iterator(반복자)를 이용하여 요소에 접근하고 만약 그 값이 삭제를 원하는 값과 동일할 때, 해당 Iterator(반복자)를 삭제하는 방법도 가능합니다.
HashSet 예외처리
while (iterator.hasNext()) {
try {
String element = iterator.next();
System.out.println(element);
} catch (NoSuchElementException e) {
// 예외 처리
}
}
만약 'next()' 메서드를 호출하기 전에 'hasNext()'를 확인하지 않을 경우에는 'NoSuchElementException'이 발생할 수 있으므로, 예외처리를 해주는 것이 좋습니다. 또한, Iterator를 사용하면 HashSet을 순회하면서 요소를 안전하게 제거할 수 있으며 내부적으로 데이터에 직접 접근하지 않아도 되는 점이 편리합니다.
마치며
지금까지 HashSet의 기본개념과 사용법, 시간복잡도에 대해 알아보았습니다. 사실 사용법들은 간단하지만, 기본개념에 대해 정확히 알아야 실무에서도 상황에 알맞은 자료구조를 선택할 수 있을 것 같아요. 오늘도 즐코하세요😊
👨👩👦👦 오픈채팅방 운영
취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁
참여코드 : 456456
https://open.kakao.com/o/gVHZP8dg
👨💻 전자책 출간
아울러 제가 🌟비전공자에서 2년 만에 보안 전문 중견기업으로 이직 한 방법들을 정리한 전자책을 출간하게 되었습니다. 어떤 걸 공부해야 하는지, 이직을 위해서 무엇을 준비해야 하는지, 제가 받았던 기술 면접 리스트 등 다양한 목차로 구성되어 있습니다. 또한, 구매 시 1:1 채팅을 이용하여 포트폴리오 첨삭을 도와드리고 있습니다. 🐕전자책으로 얻은 모든 수익은 유기견 센터 '팅*벨 입양센터'에 후원될 예정입니다. 관심 있으신 분들은 아래 링크를 참고해 주세요😁
'TIL' 카테고리의 다른 글
jstree 핸들링 방법(대용량 데이터 다루기 - 행걸리는 현상) (0) | 2024.03.07 |
---|---|
jstree 핸들링 방법(상˙하위 노드 입맛대로 선택하기) (0) | 2024.02.23 |
Java 대용량 데이터 HashMap 기본개념 및 시간복잡도(예시) (0) | 2024.02.02 |
Java 대용량 데이터 이중반복문 vs 배열 사용 속도차이(예시) (4) | 2024.01.24 |
Java 엑셀 만드는 방법 완벽정리(JS에서 Controller까지) (0) | 2024.01.15 |