자바

[Java] HashSet

nayeonee__ 2023. 3. 15. 12:25

* HashSet 이란?

- HashSet 은 Set 인터페이스의 구현클래스

 

[특징]

- 객체를 중복해서 저장할 수 없고, 하나의 null 값만 저장할 수 있다.

- 저장순서가 유지되지 않는다.

- 중복을 자동으로 제거해준다.

- 비선형 구조이기에 순서가 없고 인덱스도 존재하지 않는다.

  따라서 값을 추가하거나 삭제할 때에는 추가 혹은 삭제하고자 하는 값이 Set 내부에 있는지 검색한 뒤 추가나 삭제를 해야 하므로 속도가 List 에 비해 느리다.

 

 

<중복을 걸러내는 과정>

HashSet 은 객체를 저장하기 전에 먼저 객체의 hashCode() 메소드를 호출해서 해시 코드를 얻어낸 다음 저장되어 있는 객체들의 해시 코드와 비교한 뒤 같은 해시 코드가 있다면 다시 equals() 메소드로 두 객체를 비교해서 true 가 나오면 동일한 객체로 판단하고 중복 저장을 하지 않는다.

문자열을 HashSet 에 저장할 경우, 같은 문자열을 갖는 String 객체는 동일한 객체로 간주되고 다른 문자열을 갖는 String 객체는 다른 객체로 간주되는데, 그 이유는 String 클래스가 hashCode()와 equals() 메소드를 재정의해서 같은 문자열일 경우 hashCode() 의 리턴 값은 true 가 나오도록 했기 때문이다.

 

[사용법]

HashSet 선언

HashSet<Integer> set1 = new HashSet<Integer>();//HashSet생성
HashSet<Integer> set2 = new HashSet<>();//new에서 타입 파라미터 생략가능
HashSet<Integer> set3 = new HashSet<Integer>(set1);//set1의 모든 값을 가진 HashSet생성
HashSet<Integer> set4 = new HashSet<Integer>(10);//초기 용량(capacity)지정
HashSet<Integer> set5 = new HashSet<Integer>(10, 0.7f);//초기 capacity,load factor지정
HashSet<Integer> set6 = new HashSet<Integer>(Arrays.asList(1,2,3));//초기값 지정

HashSet 을 기본으로 생성했을 때에는 initial capacity(16), load factor(0.75) 의 값을 가진 HashSet 객체가 생성된다.

HashSet 도 저장공간보다 값이 추가로 들어오면 List 처럼 저장공간을 늘리는데 Set 은 한 칸씩 저장공간을 늘리지 않고 저장용량을 약 두 배로 늘린다. 여기에서 과부하가 많이 발생된다.

그렇기에 초기에 저장할 데이터 갯수를 알고 있다면 Set 의 초기 용량을 지정해 주는 것이 좋다.

 

[HashSet 값 추가]

HashSet<Integer> set = new HashSet<Integer>();//HashSet생성
set.add(1); //값 추가
set.add(2);
set.add(3);

HashSet 에 값을 추가하려면 HashSet의 add(value) 메소드를 사용하면 된다.

입력되는 값이 HashSet 내부에 존재하지 않는다면 그 값을 HashSet 에 추가하고 true 를 반환하고 

내부에 값이 존재한다면 false 를 반환한다.

 

[HashSet 값 삭제]

HashSet<Integer> set = new HashSet<Integer>(Arrays.asList(1,2,3));//HashSet생성
set.remove(1);//값 1 제거
set.clear();//모든 값 제거

HashSet에 값을 제거하려면 HashSet의 remove(value) 메소드를 사용하면 된다.

매개변수 value 의 값이 HashSet 내부에 존재한다면 그 값을 삭제한 후 true 를 반환하고 없다면 false 를 반환한다.

모든 값을 제거하려면 clear() 메소드를 사용하면 된다.

 

 

[HashSet 크기 구하기]

HashSet<Integer> set = new HashSet<Integer>(Arrays.asList(1,2,3));//HashSet생성
System.out.println(set.size());//set 크기 : 3

HashSet 의 크기를 구하려면 size() 메소드를 사용하면 된다.

 

[HashSet 값 출력]

HashSet<Integer> set = new HashSet<Integer>(Arrays.asList(1,2,3));//HashSet생성

System.out.println(set); //전체출력 [1,2,3]
		
Iterator iter = set.iterator();	// Iterator 사용
while(iter.hasNext()) {//값이 있으면 true 없으면 false
    System.out.println(iter.next());
}

Set 컬렉션을 그냥 print 하게 되면 대괄호 [ ] 로 묶여서 set 의 전체값이 출력된다.

Set 에는 인덱스로 객체를 가져오는 get(index) 메소드가 없다. 

대신 전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자(Iterator)를 제공한다.

반복자 이터레이터 인터페이스를 구현한 객체를 말하는데 iterator() 메소드를 호출하면 얻을 수 있다.

Iterator 에서 하나의 객체를 가져올 때는 next() 메소드를 사용한다.

next() 메소드를 사용하기 전에 먼저 가져올 객체가 있는지 확인하는 것이 좋다.

hasNext() 메소드는 가져올 객체가 있으면 true 를 리턴하고 없으면 false 를 리턴한다.

 

 

[HashSet 값 검색]

HashSet<Integer> set = new HashSet<Integer>(Arrays.asList(1,2,3));//HashSet생성
System.out.println(set.contains(1)); //set내부에 값 1이 있는지 check : true

HashSet 내부에 원하는 값이 있는지 확인하고 싶다면 contains(value) 메소드를 사용한다.

파라미터로 주어진 객체가 HashSet 을 가지고 있다면 true, 아니면 false 를 반환한다.

 

 

 

 

 

 

참고블로그 : https://coding-factory.tistory.com/554