자바[JAVA] : Set - HashSet / TreeSet / LinkedHashSet 알아보기.

2020. 12. 1. 20:36Java

반응형

- Set

- 순서를 유지하지 않는 데이터의 집합. 데이터의 중복을 허용하지 않는다.

- 인덱스로 요소들을 관리하지 않는다.

예를 들어 나의 판매사이트의 하루 방문자 수(중복 접속을 제외한)를 구하고 싶을때, 126번째 손님이 중복으로 많이 들어올 경우 여러번이 아닌 한번 접속된 걸로 설정해야한다. (Set의 중복 허용 x 성질)

(구현 클래스 : HashSet, TreeSet, LinkedHashSet)

Set의 Collection 종류와 특징.


- Set 컬렉션의 공통적인 주요 메서드.

Set 주요 메서드.


HashSet 

HashSet은 Set인터페이스를 구현한 가장 대표적인 컬렉션이며, 특징대로 중복된  데이터를 저장할 수 없으며 순서를 유지하지 않는다.(자체적인 저장 방식에 따라 순서가 결정)

Set<변수 타입> 객체명 = new HashSet<변수 타입>();

HashSet<변수 타입> 객체명 = new HashSet<변수 타입>();

위 두 문장은 같은 의미 이지만, 되도록이면 맨 위 방법인 Set타입의 참조변수로 선언하는 것을 추천한다. 만일 HashSet을 선언하게되면 추 후 TreeSet과같은 다른 컬렉션으로 바꿔야 한다면 그만큼 문장들을 검토해야할 필요성이 있다. 하지만 Set선언은 HashSet 선언보다 사용할 수 있는 컬렉션의 범위가 넓기 때문이다. (나머지 컬렉션도 동일.)

- HashSet의 사용법과 예제

package bokTest;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetTest {

	public static void main(String[] args) {

		Set<String> set = new HashSet<String>();
		
		set.add("a");
		set.add("z");
		set.add("c");
		set.add("b");
		set.add("c"); //중복
		set.add("p");
		set.add("a"); //중복
		set.add("d");
		set.add("a"); //중복
		
		//Iterator 생성 방법 (*한번 생성 후 재사용 할경우 재생성 필수)
		Iterator<String> iter = set.iterator();
		
		while(iter.hasNext()) {
			System.out.println(iter.next());
		}
	}
}

결과값을 보면 add()를 사용하여 삽입된 요소의 중복이 제거된 형태를 볼 수 있으며, add()순서와 관계없이 데이터가 삽입된것을 알 수 있다. 또한 HashSet의 요소를 불러오기 위하여 Iterator(반복자)를 사용하였다.

but, 서로 다른 객체는 값이 같아도 중복으로 간주하지 않는다. ex)String a = "1"; 과 new Integer(1)은 같은 값으로 저장.

 

TreeSet 

TreeSet은 이진 검색 트리(binary search tree)라는 자료구조의 형태로 데이터를 저장하는 컬렉션 클래스이다. 중복된 데이터의 저장을 허용하지 않으며 정렬된 위치에 저장하므로 저장순서를 유지하지도 않는다. (이미 오름차순 자동정렬 완성 후 관리)값에 따라 오름차순 정렬 기준(정규식 0-9, A-Z, a-z 순)으로 정렬- TreeSet의 사용법과 예제

package bokTest;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetTest {

	public static void main(String[] args) {
		
		Set<Integer> set = new TreeSet<Integer>();
		
		set.add(80);
		set.add(50);
		set.add(90);
		set.add(10);
		set.add(60);
		
		//Iterator 생성 방법 (*한번 생성 후 재사용 할경우 재생성 필수)
		Iterator<Integer> iter = set.iterator();
		
		while(iter.hasNext()) { //iter에 다음 읽을 데이터가 있다면
			System.out.println(iter.next());
		}
	}
}

결과값을 보면 add()를 사용한 순서와 관계없이 오름차순으로 자동 정렬되는것을 볼 수 있다. (중복 또한 x)
역순 정렬 가능( NavigableSet descendingSet() )

TreeSet은 이진검색트리 구조(root와 node)이기 때문에 HashSet과는 다르게 추가된 메서드들이 존재한다.
- SortedSet headSet(Object o) : 지정된 객체(데이타)보다 작은 값의 객체들을 반환한다.
- SortedSet tailSet(Object o) : 지정된 객체(데이타)보다 큰 값의 객체들을 반환한다.
- Object pollFirst() : TreeSet의 첫번째 요소(제일 작은 값의 객체)를 반환한다.
- Object pollLast() : TreeSet의 마지막 번째 요소(제일 큰 값의 객체)를 반환한다.

TreeSet의 이진 검색 트리의 저장과정과 특징

이진 검색 트리의 저장 과정.

- TreeSet에 사용되는 이진트리는 링크드리스트처럼 여러개의 노드(node)가 서로 연결된 구조로, 각 노드에 최대 2개의 노드를 연결할 수 있으며 '루트(root)'라고 불리는 하나의 노드에서부터 시작해서 계속 확장해나간다.

- 값의 크기를 비교하면서 트리를 따라 내려가고, 작은값은 왼쪽에 큰 값은 오른쪽에 저장.

- 왼쪽 마지막 레벨이 가장 작은 값이 되고 오른쪽 마지막 레벨의 값이 가장 큰 값이 된다.

- 비교에는 TreeSet에 저장되는 객체가 Comparable을 구현하던가 아니면, Comparator를 제공해서 두 객체를 비교할 방법을 알려줘야한다. (TreeSet의 비교 구현 방식)

이진 검색 트리(binary search tree)는

  • 모든 노드는 최대 두 개의 자식노드를 가질 수 있다.
  • 왼쪽 자식노드의 값은 부모노드의 값보다 작고 오른쪽 자식노드의 값은 부모노드의 값보다 커야한다.
  • 노드의 추가 삭제에 시간이 걸린다.(순차적으로 저장하지 않으므로)
  • 검색(범위검색)과 정렬에 유리하다.
  • 중복된 값은 저장하지 못한다.

 

- LinkedHashSet 

ArrayList와 같이 List인터페이스를 구현한 컬렉션과 달리 HashSet은 저장순서를 유지하지 않는다는 것을 알 수 있었다. 저장순서를 유지하고 관리하고자 한다면 LinkedHashSet을 사용.

package javaTest;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetTest {

	public static void main(String[] args) {
		  Set<String> set = new LinkedHashSet<String>();
	      
	      set.add("a");
	      set.add("z");
	      set.add("c");
	      set.add("b");
	      set.add("c"); //중복
	      set.add("p");
	      set.add("a"); //중복
	      set.add("d");
	      set.add("a"); //중복
	      
	      //Iterator 생성 방법 (*한번 생성 후 재사용 할경우 재생성 필수)
	      Iterator<String> iter = set.iterator();
	      
	      while(iter.hasNext()) {
	         System.out.println(iter.next());
	      }
          
          //Collectionx클래스의 sort를 쓰기위하여 Set의 객체들을 list에 담아 정렬.
          List<String> list = new LinkedList(set);
	      Collections.sort(list);
	}
}

결과값을 보면 add()된 값 순서로 저장된걸 확인할 수 있다. 중복 또한 제거된 값을 확인할 수 있다.

또한 Set인터페이스의 객체들은 ArrayList 또는 LinkedList에 담을 수 있다.

마지막으로 Set은 일반 배열로 변환 할 수 있다.
타입[] 배열명 = Set명.toArray(new 타입명[Set의 크기]);

public class LinkedHashSetTest {

	public static void main(String[] args) {
		  Set<String> set = new LinkedHashSet<String>();
	      
	      set.add("a");
	      set.add("z");
	      set.add("c");
	      
	      String arr[] = set.toArray(new String[set.size()]);
          for(String i : arr){
          	System.out.println(i);
          }
	}
}

 

출처 : 자바의 정석 2권 Collection

반응형