IT/자바

HashMap, HashTable, HashSet 의 차이점 외 기타

Beautifulkim 2018. 5. 14. 12:03

출처: http://swalloow.tistory.com/36 [MyCloud]


Set - HashSet


자바 컬렉션에서 제공하는 Set 인터페이스는 순서를 유지하지 않는 데이터의 집합입니다.
Map 구조와 달리 중복을 허용하지 않는다는 특징이 있습니다.
HashSet은 내부적으로 해싱(Hashing)을 이용해서 구현한 컬렉션입니다.
HashSet은 저장순서를 유지하지 않으므로 저장순서를 유지하려면 LinkedHashSet을 사용해야 합니다.








JAVA의 HashSet 구현


HashSet 을 활용한 아래 코드를 통해 주요 메서드와 사용법을 알아보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class HashSetTest {
    public static void main(String[] args) {
        String[] strArr = {"a""a""b""c""d""e"};
        Set<String> set =  new HashSet<String>();
        
        for(int i = 0; i < strArr.length; i++) {
            set.add(strArr[i]);
        }
        for(String str: strArr) {
            set.add(str);
        }
        
        System.out.println(set);
        
        set.remove("b");
        set.removeAll(set);
        set.clear();
    }
}
cs


저장하는 배열은 스트링 타입으로 지정하였습니다.
HashSet은 Set 인터페이스를 상속받기 때문에 위와 같이 생성하였습니다.

HashSet에 객체를 추가할 때 add 메서드를 사용합니다.
첫번째는 for문을 통해 배열의 길이만큼 반복문을 돌리는 방법,
두번째는 요소를 하나씩 저장하는 방법입니다.
HashSet은 중복되는 값을 무시하기 때문에 저장 결과는 (a, b, c, d, e) 가 됩니다.


remove는 지정된 객체를 HashSet에서 삭제하는 메서드,
removeAll과 clear는 저장된 모든 객체를 삭제하는 메서드입니다.
이 밖에도 isEmpty, contains, size 등의 메서드가 있습니다.







Set - TreeSet


TreeSet은 이진탐색트리(BinarySearchTree)의 형태로 데이터를 저장하는 컬렉션입니다.
이진탐색트리 중에서도 성능을 향상시킨 '레드-블랙 트리(Red-Black Tree)로 구현되어 있습니다.
따라서 데이터의 추가, 삭제에는 시간이 걸리지만, 검색과 정렬이 뛰어나다는 장점이 있습니다.
TreeSet은 마찬가지로 중복된 데이터의 저장을 허용하지 않으며 정렬된 위치에 저장하므로 

저장순서를 유지하지 않습니다.







JAVA의 TreeSet 구현


TreeSet을 활용한 아래 코드를 통해 주요 메서드와 사용법을 알아보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<String>();
        
        set.add("apple");
        set.add("airplane");
        set.add("alien");
        set.add("disc");
        set.add("dance");
        
        System.out.println(set.headSet("b"));
        System.out.println(set.subSet("a""al"));
        System.out.println(set.tailSet("c"));
        
    }
}
cs


add 메서드는 지정된 객체를 TreeSet에 저장하는 메서드 입니다.
a로 시작하는 단어 3개, d로 시작하는 단어 2개를 저장하였습니다.


headSet, subSet, tailSet은 TreeSet의 중요한 메서드입니다.
headSet은 지정된 객체보다 작은 값의 객체들을 반환합니다.
위의 경우 "b" 보다 작은 값인 "a"로 시작하는 객체들을 반환합니다. (apple, airplane, alien)
subSet은 범위검색의 결과를 반환합니다. 앞에 오는 것이 from, 뒤에 오는 것이 to 입니다.
따라서 위의 경우 "a" 와 "al" 사이의 객체들을 반환합니다. (airplane)
tailSet은 지정된 객체보다 큰 값의 객체들을 반환합니다.
위의 경우에는 "c" 보다 큰 값인 "d"로 시작하는 객체들을 반환합니다. (disc, dance)

이처럼 TreeSet은 문자열 검색, 자동완성 등과 같은 곳에도 활용할 수 있습니다.


===============================================================

출처: http://darksilber.tistory.com/entry/HashMap-HashTable-HashSet-의-차이점-외-기타 [안드로이드 / 자바]


HashSet과 TreeSet 비교


HashSet과 TreeSet 모두 중복을 허용하지 않고 순서가 없는 컬렉션입니다.

1. 구현 방식
 - HashSet은 해싱을 이용하여 구현
 - TreeSet은 이진탐색트리를 이용하여 구현

2. 속도 비교
 - HashSet > TreeSet
 - 해싱이 이진탐색트리보다 빠르다

3. 정렬 기능
 - HashSet < TreeSet
 - 이진탐색트리를 이용했기 때문에 데이터 정렬이 가능 (Comparator 이용)



출처 - http://www.mfamstory.com/

포스트 내용의 참고자료 출처 : 소설같은자바 Third Edition

JAVA에서 기본적인 자료 구조를 제공하기 위한 환경을 JAVA Collection Framework라고 한다.

다음은 JAVA Collection Framework의 상속 기본 구조이다.

  1. Collection

    Collection 인터페이스를 상속받아 List와 Set 인터페이스가 된다. List는 순서가 있는 Collection, 그리고 List는 Data 중복을 허락한다. 하지만 Set은 순서의 의미가 없으며 Data를 중복해서 포함할 수 없다.

  • List 인터페이스의 특징
    • 순서가 있는 Collection.(이 순서는 삽입된 순서를 의미한다.)
    • Data를 중복해서 포함할 수 있다.
    • Stack의 특징
      • Data의 삽입과 추출이 후입선출(Last-In First-Out) 구조로 되어 있다.
      • push() method : Data 삽입할 때 사용
      • pop() method : Data 추출할 때 사용
      • peek() method : 추출할 Data를 삭제하지 않고 Data만을 가져 올 때 사용
      • search() method : Stack으로부터 Data를 검색할 때 사용
    • Vector의 특징
      • 자동으로 동기화를 보장해준다.
      • ArrayList에 동기화가 보장되도록 최적화한 클래스이다.
      • JAVA 5.0 이 후로는 AutoBoxing/AutoUnBoxing을 지원한다.
        • AutoBoxing이란? 기본 Data 타입을 Wrapper 클래스형의 객체로 자동으로 변환해주는 기능. AutoUnBoxing은 AutoBoxing의 반대 개념
        • JAVA 1.4까지

Vector v = new Vector();
v.addElement(new Integer(100));

  • JAVA 5.0이후

Vector v = new Vector();
v.addElement(100); // AutoBoxing 발생, 자동으로 Wrapper class인 Integer로 변경

  • addElement() method : Data를 삽입할 때 사용
  • elementAt() method : Data를 추출할 때 사용, Index에 해당하는 객체를 얻어냄
  • size() method : Vector 내에 존재하는 객체의 수를 얻어낼 대 사용
  • insertElementAt() method : Vector 내에 중간 삽입할 때 사용
  • setElementAt() method : Vector 내에 존재하는 Data를 수정할 때 사용
  • indexOf() method : Vector 내에 Data를 검색할 때 사용, Index를 반환
  • contains() method : Data의 존재 유무를 알기 위해 사용.
  • ArrayList의 특징
    • 동기화를 보장해주지 않는다.
    • 배열에 동적 메모리 증가 기능을 구현한 클래스이다.
    • 동기화 지원 방법 : List list = Collections.synchronizeList(new ArrayList(…));
    • add() method : Data 삽입할 때 사용
    • get(0 method : Data 추출할 때 사용
    • toArray() method : ArrayList로부터 배열 얻어낼 때 사용
    • contains() method : Data의 존재 유무를 알기 위해 사용
    • size() method : ArrayList의 요소 개수를 얻어낼 때 사용
  • Set 인터페이스의 특징
    • 집합적인 개념의 Collection
    • 순서의 의미가 없다.
    • Data를 중복해서 포함할 수 없다.
    • HashSet의 특징
      • add() method : Data 삽입할 때 사용
      • next() method : Data 추출할 때 사용
        • HashSet의 Data 추출은 Iterator을 이용하면 된다. Iterator는 Collection내의 모든 Data에 접근할 수 있는 특징이 있다. 그리고 Data의 마지막에 상관하지 않고 검색하기 위한 인터페이스이다. Set의 Iterator() method로 Iterator를 얻어 낼 수 있으며, Iterator의 hasNext() method를 이용해서 Data 끝을 만날 때까지 next() method를 호출해서 Data를 추출할 수 있다.

Iterator<String iter = set.iterator();
while(iter.hasNext()) {
String temp = iter.next();

System.out.print(temp + ", ");
}

  • remove() method : Data를 삭제할 때 사용
  • contains() method : Data의 포함여부를 알기 위해 사용
  • size() method : HashSet의 요소 개수를 얻어낼 때 사용

  1. Map

    List와 Set이 순서나 집합적인 개념의 인터페이스라면 Map은 검색의 개념이 가미된 인터페이스이다. Map 인터페이스는 데이터를 삽입할 때 Key와 Value의 형태로 삽입되며, Key를 이용해서 Value를 얻을 수 있다.

  • Hashtable, HashMap의 공통점
    • 내부적으로 모두 Hash 기법을 이용한다.
    • Map 인터페이스를 구현하고 있다.
    • Key와 Value를 이용해서 Data를 관리한다.
  • Hashtable, HashMap의 차이점
    • Hashtable은 동기화가 보장된다.
    • HashMap은 동기화가 보장되지 않는다.
    • HashMap의 동기화 지원 방법 : Map m = Collections.synchronizedMap(New HashMap(…));
  • Hashtable, HashMap과 HashSet과의 관계
    • Hashtable과 HashMap은 둘 다 Map 인터페이스를 구현하고 있다.
    • HashSet은 내부적으로 Hash기법을 사용하지만 Set인터페이스를 구현하고 있다.
  • HashMap
    • 객체 생성 : Map<String, Integer> map = new HashMap<String, Integer>();
    • put() method : Data 삽입할 때 사용
    • get() method : Data를 추출할 때 사용, argument값은 Key를 사용
  • Hashtable
    • 객체 생성 : Hashtable<String, Object> h = new Hashtable<String, Object>();
    • put() method : Data 삽입할 때 사용
    • get() method : Data를 추출할 때 사용, argument값은 Key를 사용

  1. Sorted

    Set과 Map 인터페이스를 상속받아 정렬 기능이 추가된 SortedSet과 SortedMap 인터페이스가 된다. 그리고 이들은 각각 TreeSet 클래스와 TreeMap 클래스로 구성된다. TreeSet과 TreeMap은 Set과 Map의 기능을 가지고 있으면서 정렬 기능이 가미되었다는 것이 특징이다.

  • Sorted를 지원하지 않는 클래스
    • HashSet, HashMap
  • Sorted를 지원하는 클래스
    • TreeSet, TreeMap
  • TreeMap
    • Key와 Value로 Data를 관리
    • Key를 기준으로 오름차순으로 정렬된다.
    • Map 인터페이스를 상속한 SortedMap 인터페이스를 구현한 클래스
  • TreeSet
    • Set 인터페이스를 상속한 SortedSet 인터페이스를 구현한 클래스
    • 데이터들이 자동으로 오름차순으로 정렬된다.
  • Comparator
    • TreeSet과 TreeMap은 사용자가 직접 정렬의 방식을 지정할 수 있다.
    • TreeSet과 TreeMap은 정렬을 위한 Comparator 인터페이스를 구현하면 된다.
    • TreeSet에 Data를 집어 넣으면 기본적으로 오름차순(Ascending) 정렬이 되지만 그것도 문자열이나 기본 데이터 타입과 같은 단순한 것에만 해당된다. 이에 사용자가 직접 비교법을 넣어주기 위해 사용하는 것이 Comparator 인터페이스이다.
    • Comparator의 구현 방법 : Comparator 내부에 compare() method를 구현하면 된다.

class Mycomparator<T> implements Comparator<T> {
public int compare(T o1, T o2) {
// 비교방법 구현
}

  • Comparator가 추가된 TreeSet의 생성

TreeSet<Score> tset = new TreeSet<Score>(new MyComparator<Score>());

  • Comparator가 추가된 TreeMap의 생성

TreeMap<Score, String> tset = new TreeMap<Score, String>(new MyComparator<Score>());

  • 일반적인 정렬기능의 사용
    • HashSet이나 HashMap을 정렬 기능이 지원되는 TreeSet이나 TreeMap으로 변환해서 사용
    • HashSet을 이용한 TreeSet 생성

Set<String> set = new HashSet<String>();
...
TreeSet<String> ts = new TreeSet<String>();
ts.addAll(set);

  • HashMap을 이용한 TreeMap 생성

Map<String, Integer> map = new HashMap<String, Integer>();
...
Map<String, Integer> sortedMap = new TreeMap<String, Integer>();
sortedMap.putAll(map);