본문 바로가기
Java

[Java] Collection Framework2 - Set(HashSet / LinkedHashSet / TreeSet)

by 건복치 2020. 4. 25.
반응형

Set 컬렉션

  • 저장 순서가 유지되지 않음

  • 객체를 중복해서 저장할 수 없음

  • 하나의 null만 저장할 수 있음

  • Set 인터페이스의 구현 클래스로 HashSet, LinkedHashSet, TreeSet 등이 있다.

Set 인터페이스 메소드

기능 메소드 설명
객체 추가 boolean add(E e) 주어진 객체를 저장
객체가 성공적으로 저장되면 true 리턴
중복 객체면 false 리턴
객체 검색 boolean contains(Object o) 주어진 객체가 저장되어 있는지 여부 반환
- boolean containsAll(Collection<?> c)
isEmpty() 컬렉션이 비어 있는지 조사
Iterator<E> iterator() 저장된 객체를 한 번씩 가져오는 반복자 리턴
int size() 저장되어 있는 전체 객체 수 리턴
Object toArray() 저장된 객체들을 객체 배열의 형태로 반환
객체 삭제 void clear() 저장된 모든 객체를 삭제
boolean remove(Object o) 주어진 객체를 삭제
- boolean removeAll(Collection<?> c)

 

Java API - Set

 

Iterator

Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없다.

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

Set<String> set = ...;
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
	//String 객체를 하나 가져옴
    String atr = iterator.next();
}

 

Iterator 포스트

 

Iterator를 사용하지 않더라도 향상된 for문을 이용해서 전체 객체를 대상으로 반복할 수 있다.

Set<String> set = ...;
for(String str : set) {

}

 

HashSet

해쉬 테이블에 원소를 저장하기 때문에 성능면에서 가장 우수하다.

단 객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않는다.

 

HashSet이 판단하는 동일한 객체란 꼭 같은 인스턴스를 뜻하지는 않는다.

HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 메소드를 호출해서 해시 코드를 얻어낸다.

그리고 이미 저장되어 있는 객체들을 해시 코드와 비교한다.

만약 동일한 해시 코드가 있다면 다시 equals() 메소드로 두 객체를 비교해서 true가 나오면 동일한 객체로 판단하고 중복 저장을 하지 않는다.

 

ex. 문자열을 HashSet에 저장할 경우, 같은 문자열을 갖는 String 객체는 동등한 객체로 간주되고 다른 문자열을 갖는 String 객체는 다른 객체로 간주된다.

왜냐하면 String 클래스가 hashCode()와 equals() 메소드를 재정의해서 같은 문자열일 경우 hashCode()의 리턴 값을 같게, equals()의 리턴 값은 true가 나오도록 했기 때문이다.

 

HashSet<E> set = new HashSet<E>();

 

HashSet 출력 관련 포스트

 

LinkedHashSet

해쉬 테이블과 연결 리스트가 결합된 형태로 원소들의 순서는 삽입되었던 순서와 같다.

 

즉, 중복된 데이터를 저장할 수 없다.

하지만 입력된 순서대로 데이터를 관리한다.

 

Java API  - LinkedHashSet

 

TreeSet

  • HashSet과 마찬가지로 중복된 데이터를 저장할 수 없고, 입력한 순서대로 값을 저장하지 않는다.

  • 이진트리를 기반으로 한 set컬렉션이기에 계층적 구조(tree 구조)를 가지면서 객체를 저장한다. 

  • 하나의 노드는 노드 값인 value와 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성된다.

  • 트리의 특성상 저장할 때부터 정렬을 한다. 그래서 기본적으로 오름차순으로 데이터를 정렬한다.

  • 부모 값과 비교해 낮은 것은 왼쪽 자식 노드에, 높은 것은 오른쪽 자식 노드에 저장한다.

  • 레드-블랙 트리(red-black tree)에 원소를 저장하므로 값에 따라서 순서가 결정되며 속도가 HashSet보다 느리다.

  • 검색, 정렬 기능 뛰어남 / 데이터 추가, 삭제 시간 오래 걸림

  • ex. 문자열의 정렬 순서(문자의 코드값이 기준)

    • 오름차순일 경우 : 공백 -> 숫자 -> 대문자 -> 소문자

    • 내림 차순일 경우 : 공백 <- 숫자 <- 대문자 <- 소문자

 

 

TreeSet<E> treeSet = new TreeSet<E>();

TreeSet<String> treeSet = new TreeSet<String>();

 

TreeSet의 검색 관련 메소드

리턴 타입 메소드 설명
E first() 제일 낮은 객체를 리턴
E last() 제일 높은 객체를 리턴
E lower(E e) 주어진 객체보다 바로 아래 객체를 리턴
E higher(E e) 주어진 객체보다 바로 위 객체를 리턴
E floor(E e) 주어진 객체와 동등한 객체가 있으면 리턴,
만약 없다면 주어진 객체의 바로 아래 객체를 리턴
E ceiling(E e) 주어진 객체와 동등한 객체가 있으면 리턴,
만약 없다면 주어진 객체의 바로 위의 객체를 리턴
E pollFirst() 제일 낮은 객체를 꺼내오고 컬렉션에서 제거함
E pollLast() 제일 높은 객체를 꺼내오고 컬렉션에서 제거함

 

TreeSet의 정렬 관련 메소드

리턴 타입 메소드 설명
Iterator<E> descendingIterator() 내림차순으로 정렬된 Iterator를 리턴
NavigableSet<E> descendingSet() 내림차순으로 정렬된 NavigableSet을 반환

 

  • descendingIterator() 메소드는 위의 Iterator 사용 방법대로 사용하면 됨
  • descendingSet() 메소드에서 NavigableSet은 TreeSet과 마찬가지로 검색 관련 메소드를 제공하고 정렬 순서를 바꾸는 descendingSet()메소드도 제공하는 set 컬렉션 구현 클래스이다.
  • 오름차순은 descendingSet() 메소드를 두 번 호출하면 된다.

TreeSet의 범위 검색 관련 메소드

더보기
리턴 타입 메소드 설명
NavigableSet<E> headSet(
    E toElement,
    boolean inclusive
)
- 객체 / 포함여부

- 주어진 객체보다 낮은 객체들을 NavigableSet으로 리턴.
주어진 객체 포함 여부는 2번째 매개값에 따라 달라짐
NavigableSet<E> tailSet(
    E fromElement,
    boolean inclusive
)
- 객체 / 포함여부

- 주어진 객체보다 높은 객체들을 
NavigableSet으로 리턴.
주어진 객체 포함 여부는 2번째 매개값에 따라 달라짐
NavigableSet<E> subSet(
    E fromElement, 
    boolean fromInclusive,
    E toElement,
    boolean toInclusive
)
- 시작 객체 / 포함여부 / 끝 객체 / 포함여부

- 시작과 끝으로 주어진 객체 사이의 객체들을 NavigableSet으로 리턴.
시작과 끝 객체의 포함 여부는 2번째, 4번째 매개값에 따라 달라짐

 

ex) subSet() 사용법

시작 객체 < 찾는 객체 < 끝 객체

시작 객체 <= 찾는 객체 <= 끝 객체

 

TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("apple");
treeSet.add("banana");
treeSet.add("cherry");
treeSet.add("disert");
treeSet.add("zoo");

//c에서 f사이의 단어 검색;
NavigableSet<String> rangeSet = treeSet.subSet("c", true, "f", true);
for(String word : rangeSet) {
	System.out.println(word);
}

 

출력 결과

 

cherry
disert

 

 

 

[Java] 자바 TreeSet 사용법 & 예제 총정리
Java API - TreeSet 

 

관련 포스트

[Java] Collection Framework1 - List(ArrayList / Vector / LinkedList)
[Java] Collection Framework 3 - Map(HashMap / LinkedHashMap / TreeMap / HashTable/ Properties)

 

참고

이것이 자바다 - 신용권의 Java 프로그래밍 정복 2
https://pridiot.tistory.com/72 [[Java] HashSet, TreeSet]

 

반응형

댓글