<--! [JAVA] TreeSet, LinkedHashSet and HashSet 차이점 이해하기 -->

[JAVA] TreeSet, LinkedHashSet and HashSet 차이점 이해하기

필그램

·

2017. 9. 29. 01:35



SET의  종류별 쓰임에 대해 알아보고자 합니다.

TreeSetLinkedHashSet 과 HashSet 은 자바에서 컬렉션 프레임워크를 구현하고, 객체를 저장하는데 쓰입니다.


먼저  TreeSet의 주요특징은 정렬(Sorting)입니다. 트리의 특성상 저장할때 부터 정렬을 하기 때문입니다.


LinkedHashSet은 순서를 넣는 것이며, HashSet은 순서의 정렬을 가지지 않고, 컬렉션의 객체 저장을 목적으로하는 일반적인 Set입니다.


HashSet은 자바의 HashMap을 사용하여 구현합니다.  반면 TreeSet 은 TreeMap을 가지고 구현하는 특징이 있습니다.

 위에서도 언급했지만,  TreeSet은 소팅되어 구현하므로, 각 요소를 Comparable or Comparator interface를 이용하여 소팅하여 저장합니다.


여기서 Comparable은 기본적 정렬이고, Comparator는 사용자 정의 소팅을 합니다.  이것은 사용자가 TreeSet을 정의할때 만들어집니다.


다음은 세가지set의 공통점입니다.

1) 중복 : 모든 Set의 공통점으로 중복을 허용하지 않습니다. 같은 것을 넣으면, 새로운 내용으로 대치된다고 볼 수 있습니다. 하지만, 내용은 같은 것입니다.


2) 쓰레드의 안전성 : HashSetTreeSet 와 LinkedHashSet 모두 쓰레드(Thread)에 안전하지 않습니다.


3) Fail-Fast Iterator : Iterator returned by TreeSetLinkedHashSet and HashSet are fail-fast Iterator. i.e. If Iterator is modified after its creation by any way other than Iterators remove() method, it will throw ConcurrentModificationException with best of effort. read more aboufail-fast vs fail-safe Iterator here



package MethodExe;

import java.util.*;


public class IteratingE {


public static void main(String[] args) {

// TODO Auto-generated method stub

HashSet<String> fruits1 = new HashSet<String>();

        LinkedHashSet<String> fruit2 = new LinkedHashSet<String>();

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

      

        for(String fruit: Arrays.asList("망고", "사과", "바나나")){

            fruits1.add(fruit);

            fruit2.add(fruit);

            fruit3.add(fruit);

        }

       

        //HashSet 출력

        System.out.println("HashSet :" + fruits1);


        //LinkedHashSet 출력

        System.err.println(" LinkedHashSet :" + fruit2);


        //TreeSet 출력

        System.out.println("TreeSet :" + fruit3); 

     


        //실행속도 테스트  - 백만개 입력

        Set<Integer> numbers = new HashSet<Integer>();

        long startTime = System.nanoTime();

        for(int i =0; i<1000000; i++){

            numbers.add(i);

        }


        long endTime = System.nanoTime();

        System.out.println(" HashSet에 걸린시간 : "

                            + (endTime - startTime));

      

      

        // LinkedHashSet 실행속도 테스트 

        numbers = new LinkedHashSet<Integer>();

        startTime = System.nanoTime();

        for(int i =0; i<1000000; i++){

            numbers.add(i);

        }

        endTime = System.nanoTime();

        System.out.println("LinkedHashSet 에 걸린시간 : "

                            + (endTime - startTime));

       

        // TreeSet 실행속도 테스트

        numbers = new TreeSet<Integer>();

        startTime = System.nanoTime();

        for(int i =0; i<1000000; i++){

            numbers.add(i);

        }

        endTime = System.nanoTime();

        System.out.println("TreeSet 에 걸린시간 : "

                            + (endTime - startTime));

}


}


[결과]

HashSet :[망고, 사과, 바나나]

 LinkedHashSet :[망고, 사과, 바나나]

TreeSet :[망고, 바나나, 사과]

 HashSet에 걸린시간 : 238258315

LinkedHashSet 에 걸린시간 : 975215485

TreeSet 에 걸린시간 : 309998932




각 코드는 각 셋을 이름만 바꾼 것이므로 만들어 보시거나, 복사해서 사용해 보시면 됩니다.
나노타임은 
1,000,000,000이 1초 입니다.

계산에 해시셋, 링크드 해시셋, ㅊ순으로 시간이 많이 걸립니다.

링크드 해시셋은 순서와 함께 집어넣느라 좀더 걸리고, 트리셋은 각 이전 내용과 비교해가며 넣기때문에 더 걸립니다.


HashSet으로 만든 배열을 순서로 정렬하는 방법은 TreeSet으로 바꾸는 것입니다.

예는 아래와 같습니다.


Set<String> setOfBooks = new HashSet<>();

setOfBooks.add("망고");

setOfBooks.add("Lord of Ling");

setOfBooks.add("Making the cut");

setOfBooks.add("Fire");


Set<String> bookOrder = new TreeSet<>(setOfBooks);

bookOrder.forEach(System.out::println);









반응형