Java Set 컬렉션 심층 분석

Set 계열 컬렉션 특성

Set 인터페이스는 Collection 계층구조에서 유일성과 순서 제어를 제공합니다. 주요 구현체별 특징:

public class SetExample {
    public static void main(String[] args) {
        // HashSet: 순서 없음, 중복 불가
        // Set<String> items = new HashSet<>();
        
        // LinkedHashSet: 삽입 순서 유지
        // Set<String> items = new LinkedHashSet<>();
        
        // TreeSet: 자동 정렬
        Set<String> items = new TreeSet<>();
        
        items.add("DataA");
        items.add("DataC");
        items.add("DataC"); // 중복 시도
        items.add("DataB");
        System.out.println(items); // [DataA, DataB, DataC]
    }
}

HashSet의 해시 기반 동작 원리

HashSet은 해시 테이블로 구현되며 객체의 해시값을 기반으로 저장 위치를 결정합니다.

class Employee {
    private String id;
    private int experience;
    
    public Employee(String id, int exp) {
        this.id = id;
        this.experience = exp;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Employee emp = (Employee) obj;
        return experience == emp.experience && id.equals(emp.id);
    }
    
    @Override
    public int hashCode() {
        return 31 * id.hashCode() + experience;
    }
}

public class HashAnalysis {
    public static void main(String[] args) {
        Employee emp1 = new Employee("E1001", 3);
        Employee emp2 = new Employee("E1002", 3);
        System.out.println(emp1.hashCode()); 
        System.out.println(emp2.hashCode());
    }
}

해시 테이블 구조

  • JDK 8 이전: 배열 + 연결 리스트
  • JDK 8 이후: 배열 + 연결 리스트 + 레드-블랙 트리

요소 추가 시 hashCode()로 버킷 위치 계산, equals()로 중복 검증. 버킷 내 요소 8개 초과 시 트리 구조로 변환됩니다.

중복 요소 처리 메커니즘

사용자 정의 객체의 중복 판단을 위해 hashCode()와 equals() 메서드 재정의가 필요합니다.

public class DeduplicationDemo {
    public static void main(String[] args) {
        Set<Employee> staff = new HashSet<>();
        Employee e1 = new Employee("DEV01", 2);
        Employee e2 = new Employee("DEV01", 2); // 중복 데이터
        
        staff.add(e1);
        staff.add(e2);
        System.out.println(staff.size()); // 1
    }
}

LinkedHashSet의 순서 유지

삽입 순서 보장이 필요한 경우 LinkedHashSet을 사용하며, 내부적으로 이중 연결 리스트로 순서를 관리합니다.

public class OrderPreservation {
    public static void main(String[] args) {
        Set<Employee> orderedSet = new LinkedHashSet<>();
        orderedSet.add(new Employee("T001", 5));
        orderedSet.add(new Employee("T002", 3));
        orderedSet.add(new Employee("T003", 7));
        
        // 출력 순서: T001 → T002 → T003
        orderedSet.forEach(System.out::println);
    }
}

태그: java set HashSet LinkedHashSet TreeSet

7월 5일 19:34에 게시됨