Set 컬렉션은 저장 순서가 유지되지 않으며, 객체의 중복 저장이 불가능합니다.
구현 클래스는 'HashSet', 'LinkedHashSet', 'TreeSet'이 있습니다.
Set 컬렉션에서 사용되는 주요 메서드는 다음과 같습니다.
- boolean add(E e) : 주어진 객체를 저장하고 저장이 성공하면 ture, 아니면 false를 리턴
- boolean contains(Object o) : 주어진 객체가 저장되어 있는지 여부
- isEmpty() : 컬렉션이 비어있는지 조사
- Iterator <E> iterator() : 저장된 객체를 한번씩 가져오는 반복자 리턴
- int size() : 저장되어 있는 전체 객체 수 리턴
- void clear() : 저장된 모든 객체를 삭제
- boolean remove(Object o) : 주어진 객체를 삭제
해쉬 셋( HashSet )
HashSet은 동일 객체나 동등 객체는 중복 저장하지 않습니다.
해쉬코드는 논리적인 주소가 동일하게 나올 수 있기 때문에, 해쉬코드가 동일하다면 재정의한 eqauls() 메서드를 통해 비교합니다.
@Log4j2
@AllArgsConstructor
public class Member {
public String name;
public Integer age;
// 중복 판정을 위해서 Override(재정의)
@Override
public boolean equals(Object obj) {
log.trace("equals({}) invoked.", obj);
if(obj instanceof Member member) {
// Member member = (Member) obj;
return member.name.equals(name) && (member.age == age);
} else {
return false;
} // if-else
} // equals
@Override
public int hashCode() {
log.trace("hashCode({}) invoked.");
return name.hashCode() + age;
} // hashCode
} // end class
해쉬코드는 동일할 수 있기 때문에,동일 객체의 여부를 판단할 수 있는 알고리즘을 가지고 메서드를 오버라이드해야 합니다.
다음은 실행클래스입니다.
@Log4j2
public class HashSetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// 요소 객체 추가
set.add("Java");
set.add("JDBC");
set.add("Servlet/JSP");
set.add("Java");
set.add("iBATIS");
// 객체의 크기 반환
int size = set.size();
log.info("총 객체 수 : {}", size);
// 객체들을 순회(Traverse)
// Iterator<E> 객체를 필요로 한다
Iterator<String> iterator = set.iterator(); // ---- 1
while(iterator.hasNext()) { // ---- 2
String element = iterator.next(); // ---- 3
log.info("element : {}", element);
} // while
System.out.println(); // 개행
// ------------------------------------------
// 두 번째 방법 - Enhanced for
for(String element : set) {
log.info("element : {}", element);
} // Enhanced for
// 세 번째 방법 - forEach(Consume<E>) 메서드로 순회
set.forEach(log::info);
// ·
// ·
// ·
// ·
} // main
} // end class
위 코드처럼, 다양한 순회 방법이 있습니다.
만약, HashSet에 같은 필드 정보의 2개의 객체가 add() 메서드로 추가된다면
첫 번째 객체만 추가되고, 두 번째로 add 시도되는 객체는 추가되지 않습니다.
목적에 맞게 컬렉션을 다 사용한 후에는, 반드시 GC가 빠르게 될 수 있도록 clear 해야 합니다.
// List, Set, Map 모두 추가/삭제/변경시에, 중복 판정 알고리즘을 통해
// 추가/삭제/변경 가능한 존재한 요소 객체인지 알 수 있음
set.remove("JDBC");
set.remove("iBATIS");
log.info("총 객체 수 : {}", set.size());
for(String element : set) {
log.info("\t{}", element);
} // enhanced for
// 컬렉션의 모든 요소를 clear 시킴
set.clear();
// 확인
if(set.isEmpty()) {
log.info("비어 있음");
} // if
} // main
} // end class
Lombok으로 더 간단하게 코드를 구성할 수 있습니다.
@Cleanup("clear")
// ·
// ·
// ·
// ·
// List, Set, Map 모두 추가/삭제/변경시에, 중복 판정 알고리즘을 통해
// 추가/삭제/변경 가능한 존재한 요소 객체인지 알 수 있음
set.remove("JDBC");
set.remove("iBATIS");
log.info("총 객체 수 : {}", set.size());
log.info(set)
// log.info(set)으로 대체
// for(String element : set) {
// log.info("\t{}", element);
// } // enhanced for
// 컬렉션의 모든 요소를 clear 시킴
// set.clear(); // @Cleanup("clear") annotation으로 대체
// 확인
if(set.isEmpty()) {
log.info("비어 있음");
} // if
} // main
} // end class
위의 코드처럼 Lombok의 어노테이션을 이용하면 간결하고 가독성 좋은 코드를 구성할 수 있습니다.
'Java > Collection Framework' 카테고리의 다른 글
트리 컬렉션 (0) | 2023.08.04 |
---|---|
맵 컬렉션 (0) | 2023.08.03 |
리스트 컬렉션 (0) | 2023.08.02 |
컬렉션 프레임워크 개요 (0) | 2023.08.02 |