본문 바로가기
Old Posts/Java

[Java] HashSet 사용법 및 예제

by A6K 2021. 6. 3.

HashSet

HashSet 클래스는 Set 인터페이스를 구현한 클래스다. HashSet 클래스의 속성을 알아보기 전에 Set에 대해서 알 필요가 있다. Set은 우리말로 '집합'이라는 뜻을 가지고 있다. Set에는 데이터를 중복해서 저장할 수 없다. 동일한 데이터를 여러번 Set에 추가하더라도 결국 Set에는 하나의 데이터만 저장된다.

자바 HashSet

HashSet은 데이터를 추가한 순서를 기억하지 않는다. 추가된 데이터를 정렬해주지도 않는다. 따라서 ArrayList처럼 인덱스를 통한 접근은 불가능하다.

HashSet에 데이터를 추가하면, 객체의 hashCode() 메소드를 이용해서 HashSet에 추가하려는 데이터의 해시코드가 존재하는지 확인한다. 만약 동일한 해시코드를 갖는 객체가 존재한다면 equals() 메소드를 이용해서 두 객체를 직접 비교한다. equals() 메소드가 true를 리턴한다면 이미 같은 객체가 HashSet에 존재한다고 판단하여 중복 저장을 하지 않는다. 따라서 HashSet에 저장할 객체의 hashCode() 메소드와 equals() 메소드가 굉장히 중요하다.

HashSet 사용법

HashSet 생성

HashSet<String> set1 = new HashSet<>(); //HashSet생성
HashSet<String> set2 = new HashSet<>(otherSet);//다른 Set 혹은 다른 컬렉션으로부터 초기화
HashSet<String> set3 = new HashSet<String>(10);// 초기 용량 지정
HashSet<String> set4 = new HashSet<String>(10, 0.5f);//초기 용량과 로드팩터(load factor) 지정

HashSet을 생성할 때, 어떤 데이터를 저장할 것인지 '지네릭스(Generics)'를 이용해서 지정해줘야한다. 초기화를 하지 않으면 빈 HashSet이 생성되며, 다른 컬렉션 객체의 값들을 이용해서 HashSet을 만들도록 생성자의 인자로 넘겨줄 수도 있다.

HashSet은 내부에 해시테이블(HashMap 멤버)을 가지고 있다. 해시 테이블에 새로운 데이터를 추가한 경우, 해시 테이블에 설정된 Threshold 값 보다 저장된 데이터의 개수가 많아지면, 해시 효율이 떨어지므로 새로 더 큰 해시 테이블을 생성하고 기존에 있던 해시테이블의 데이터를 새로 생성된 더 큰 해시테이블로 옮겨준다. 이 과정에서 오버헤드가 발생한다. 따라서 미리 저장할 데이터의 개수를 알고 있으면 초기 용량을 지정해서 데이터 복사가 일어나지 않게 만들어 주는게 좋다.

load factor는 Threshold 값을 계산하는데 사용된다. 용량 * loadFactor 값이 해시테이블의 Threshold 값이 되며, 해시테이블에 저장된 데이터의 개수가 이 값을 초과하면 리사이즈 동작을 진행한다. HashSet의 초기 해시테이블 사이즈는 16이고, load factor 값은 0.75f (3/4)이다.

HashSet 값 추가

HashSet에 값을 추가하기 위해서 add() 메소드를 사용할 수 있다.

set.add("Data1");
set.add("Data2");
set.add("Data1"); // 중복 추가로 새로운 값 추가가 발생하지 않음

add() 메소드를 이용해서 HashSet에 값을 추가하면, hashCode() 값과 equals() 메소드를 이용해서 동일한 값이 있는지 체크한다. 만약 동일한 값이 없다면 HashSet에 데이터가 추가되고 true 가 리턴된다. 동일한 값이 이미 존재한다면 값이 추가되지 않고 false 가 리턴된다.

HashSet 값 제거

HashSet에서 값을 제거하기 위해서는 remove() 메소드 혹은 clear() 메소드를 사용할 수 있다.

set.remove("Data1"); // "Data1" 추가 
set.clear(); // 모든 값 제거

remove() 메소드를 이용하면 HashSet에서 특정 데이터를 제거할 수 있다. 만약 제거하라고 요청한 객체가 HashSet에 존재했으면 삭제 후 true를 반환하고, 존재하지 않았으면 false를 반환한다.

HashSet에 저장되어 있는 모든 데이터를 지우려면 clear() 메소드를 호출하면 된다.

HashSet 값 확인

set.size(); // HashSet에 저장되어 있는 데이터의 개수

set.contains("Data1"); // "Data1"이 HashSet에 포함되어 있는지 확인

// for 문으로 순회
for (String elem : set) {
    System.out.println(elem);
}

HashSet에 저장되어 있는 데이터의 개수를 확인하려면 size() 메소드를 호출하면 된다.

HashSet에는 ArrayList처럼 인덱스를 통한 값 확인 메소드가 제공되지 않는다. 대신 contains() 메소드를 이용해서 특정 객체가 HashSet 안에 저장되어 있는지 확인할 수 있다.

혹은 for each 구문을 이용해서 컬렉션 데이터를 순회하는 형태로 사용할 수 있다.

댓글