본문 바로가기

프로그래밍/자바(java)

[자바/java] Set 컬렉션 ( HashSet, TreeSet )

List 컬렉션은 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지 않는다.

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

 

Set 컬렉션에는 HashSet, LinkedHashSet, TreeSet이 있다.

 

Set은 인덱스로 관리하지 않기 때문에 인덱스로 매객값으로 갖는 메소드가 없다.

 

 

객체 추가에는 add() 메소드를 사용하고, 객체 삭제는 remove() 메소드를 사용한다.

 

Set<String> set = new HashSet<String>();
set.add("자바");
set.add("java");
set.remove("자바");

 

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

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

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

 

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

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

hashNext() 메소드는 가져올 객체가 있으면 true를 리턴하고 더 이상 가져올 객체가 없으면 flase를 리턴한다.

 

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

Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
     String str = iterator.next();
}

 

Iterator를 사용하지 않더라도 향샹된 for문을 이용할 수 있다.

 

Set<String> set = new HashSet<String>();
        
for(String str : set) {
    System.out.println(str);
}

 

 

 

HashSet

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

 

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

 

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

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

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

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

 

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

public class HashSetMain {
    public static void main(String[] args) {

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

        set.add("JAVA");
        set.add("자바");
        set.add("JAVA");
        set.add("개발에만 집중 블로그");
        set.add("JAVA는 객체지향언어입니다.");

        int size = set.size();
        System.out.println("총 객체수 : " + size);

        Iterator<String> iterator = set.iterator();
        while(iterator.hasNext()) {
            String str = iterator.next();
            System.out.println(str);
        }

        set.remove("JAVA");

        size = set.size();
        System.out.println("제거 후 총 객체수 : " + size);

        set.clear();

        if(set.isEmpty()) {
            System.out.println("비었습니다.");
        }
    }
}

 

 

 

 

 

TreeSet

 

TreeSet은 이진 트리를 기반으로 한 Set컬렉션이다.

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

TreeSet에 객체를 정하면 자동으로 정렬되는데 부모값과 비교해서 낮은 것은 왼쪽 자식 노드에, 높은 것은 오른쪽 자식 노드에 저장된다.

 

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

 

Set 인터페이스 타입 변수에 대입해도 되지만 TreeSet 클래스 타입으로 대입한 이유는 객체를 찾거나 범위 검색과 관련된 메소드를 사용하기 위해서이다.

 

import java.util.TreeSet;

public class TreeSetMain {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<Integer>();

        set.add(80);
        set.add(100);
        set.add(70);
        set.add(85);
        set.add(98);
        set.add(83);

        Integer score = null;

        score = set.first();
        System.out.println("가장 낮은 점수 : " + score);

        score = set.last();
        System.out.println("가장 높은 점수 : " + score);

        score = set.lower(new Integer(90));
        System.out.println("90점 아래 점수 : " + score);

        score = set.higher(new Integer(90));
        System.out.println("90점 위 점수 : " + score);

        score = set.floor(new Integer(98));
        System.out.println("98점 이거나 바로 아래 점수 : " + score);

        score = set.ceiling(new Integer(98));
        System.out.println("98점 이거나 바로 위 점수 : " + score);

        while(!set.isEmpty()) {
            score = set.pollFirst();
        }

        System.out.println("set이 비었습니다.");

    }
}

 

 

import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;

public class TreeSetMain {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<Integer>();

        set.add(80);
        set.add(100);
        set.add(70);
        set.add(85);
        set.add(98);
        set.add(83);

        NavigableSet<Integer> descendingSet = set.descendingSet();
        for(Integer score : descendingSet) {
            System.out.print(score + " ");
        }
        System.out.println();

        NavigableSet<Integer> ascendingSet = descendingSet.descendingSet();

        Iterator<Integer> iterator = ascendingSet.iterator();
        while(iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }


    }
}

 

 

다음 예제는 String 타입을 무작위로 TreeSet에 저장후 알파벳으로 검색해보는 예제이다.

 

 

import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;

public class TreeSetMain {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<String>();

        set.add("Java");
        set.add("C");
        set.add("C#");
        set.add("Javascript");
        set.add("C++");
        set.add("Python");
        set.add("Go");
        set.add("Ruby");
        set.add("Kotlin");
        set.add("J");

        System.out.println("[c~ f 사이의 단어 검색]");
        NavigableSet<String> Navigable = set.subSet("C", true, "J", true);
        for(String lang : Navigable) {
            System.out.print(lang + " ");
        }

    }
}