[Java] 컬렉션 프레임워크 ②

kiteB·2022년 2월 22일
0

Java2

목록 보기
11/36
post-thumbnail

[ Set 컬렉션 ]

Set 컬렉션

  • Set 컬렉션은 저장 순서가 유지되지 않는다.
  • 객체를 중복해서 저장할 수 없고, 하나의 null만 저장할 수 있다.
  • Set 컬렉션에는 HashSet, LinkedHashSet, TreeSet 등이 있다.

Set 인터페이스의 메소드들

다음은 Set 컬렉션에서 공통으로 사용 가능한 Set 인터페이스의 메소드들이다.
인덱스로 관리하지 않기 때문에 인덱스를 매개값으로 갖는 메소드가 없다.

  • Set 인터페이스가 제네릭 타입이기 때문에 메소드의 매개 변수 타입과 리턴 타입에 E라는 타입 파라미터가 있다.
    • 구체적인 타입은 구현 객체를 생성할 때 결정된다.
  • 객체 추가는 add(), 객체 삭제는 remove() 메소드를 사용한다.

✅ 예제 | String 타입 객체 저장/삭제

다음은 Set 컬렉션에 저장되는 구체적인 타입을 String으로 정해놓고, String 객체 저장/삭제하는 예제이다.

Set<String> set = ...;
set.add("자바");		//객체 추가
set.add("Java");
set.remove("자바");	//객체 삭제

Iterator

Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없는 대신, 전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자(Iterator)를 제공한다. 반복자는 Iterator 인터페이스를 구현한 객체를 말하며, iterator() 메소드를 호출하면 얻을 수 있다.

Set<String> set = ...;
Iterator<String> iterator = set.iterator();

Iterator 인터페이스에 선언된 메소드는 다음과 같다.

next() 메소드를 사용하기 전에 먼저 가져올 객체가 있는지 확인하는 것이 좋다. hasNext() 메소드는 가져올 객체가 있으면 true를 리턴하고 더 이상 가져올 객체가 없으면 false를 리턴한다. 따라서 hasNext()true를 리턴할 때 next() 메소드를 사용해야 한다!


Set 컬렉션에서 String 객체들을 반복해서 하나씩 가져오는 코드는 다음과 같다.

Set<String> set = ...;
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {	//저장된 객체 수만큼 루핑
    //String 객체 하나를 가져옴
    String str = iterator.next();	
}

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

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

Set 컬렉션에서 Iteratornext() 메소드로 가져온 객체를 제거하고 싶다면 remove() 메소드를 호출하면 된다. Iterator의 메소드이지만, 실제 Set 컬렉션에서 객체가 제거됨을 알아야 한다.

다음은 Set 컬렉션에서 "자바"를 제거한다.

while (iterator.hasNext()) {
    String str = iterator.next();
    if (str.equals("자바")) {
        iterator.remove();
    }
}

1. HashSet

HashSetSet 인터페이스의 구현 클래스이다.

HashSet 생성 방법

HashSet을 생성하기 위해서는 다음과 같이 기본 생성자를 호출하면 된다.

Set<E> set = new HashSet<E>();
  • 타입 파라미터 E에는 컬렉션에 저장할 객체 타입을 지정하면 된다.

✅ 예제 | String 객체 저장

String 객체를 저장하는 HashSet은 다음과 같이 생성할 수 있다.

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

HashSet 특징

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

HashSet이 판단하는 동일한 객체란 꼭 같은 인스턴스를 뜻하지는 않는다. HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 메소드를 호출해서 해시코드를 얻어낸다. 그리고 이미 저장되어 있는 객체들의 해시코드와 비교한다. 만약 동일한 해시코드가 있다면 다시 equals() 메소드로 두 객체를 비교해서 true가 나오면 동일한 객체로 판단하고 중복 저장을 하지 않는다.

문자열을 HashSet에 저장할 경우, 같은 문자열을 갖는 String 객체는 동등한 객체로 간주되고 다른 문자열을 갖는 String 객체는 다른 객체로 간주된다. 그 이유는 String 클래스가 hashCode()equals() 메소드를 재정의해서 같은 문자열일 경우 hashCode()의 리턴값을 같게, equals()의 리턴값은 true가 나오도록 했기 때문이다.


✅ 예제 | String 객체를 중복 없이 저장하는 HashSet

  • HashSetExample
import java.util.*;

public class HashSetExample {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("Java");
        set.add("JDBC");
        set.add("Servlet/JSP");
        set.add("Java");    //"Java"는 한 번만 저장된다.
        set.add("iBATIS");

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

        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println("\t" + element);
        }

        set.remove("JDBC");
        set.remove("iBATIS");

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

        iterator = set.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println("\t" + element);
        }

        set.clear();    //모든 객체를 제거하고 비움
        if (set.isEmpty()) {
            System.out.println("비어 있음");
        }
    }
}
  • 실행 결과
총 객체 수: 4
	Java
	JDBC
	Servlet/JSP
	iBATIS
총 객체 수: 2
	Java
	Servlet/JSP
비어 있음

[ 참고자료 ]

이것이 자바다 책
http://tcpschool.com/java/java_collectionFramework_set

profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글