본문 바로가기

Programming/JAVA

컬렉션 프레임워크(3) - Set 컬렉션 1 : Set의 개념

JAVA logo image

 

 

 

 

List와 차별화되는 Set 컬렉션의 가장 큰 특징은, 수학의 집합과 유사한 성질을 갖는다는 것입니다. 기본적으로 Set 컬렉션은 인덱스가 사용되는 List와 달리 (1) 순서가 없고, (2) 중복이 허용되지 않습니다(null도 하나만 저장할 수 있습니다). 

 

기본적으로 Set 컬렉션의 종류에는 HashSet, LinkedHasSet, TreeSet 등이 있습니다. 그리고 아래의 메서드들은 Set 컬렉션에서 공통으로 사용 가능한 Set 인터페이스의 메서드들입니다. List 컬렉션과 달리, 인덱스 개념이 없기 때문에 인덱스를 파라미터로 갖는 메서드가 없다는 것이 특징이지요.

 

기능 메서드 description
객체
추가
boolean add(E e) 주어진 객체를 저장한다. 
저장 성공 시 true, 실패 시 false를 리턴한다.
객체
검색
boolean contains(Object o) 주어진 객체가 저장되었는지 여부를 확인한다.
isEmpty( ) 컬렉션이 비어 있는지 조사한다.
Iterator<E> iterator( ) 저장된 객체를 한 번씩 가져오는 반복자를 리턴한다.
int size( ) 저장되어 있는 전체 객체 수를 리턴한다.
객체
삭제
void clear( ) 저장된 모든 객체를 삭제한다.
boolean remove(Object o) 주어진 객체를 삭제한다.

 

 

List 컬렉션 설명때도 나왔던 내용인데, 위 메서드의 파라미터 중 E로 표시된 타입은 Set 인터페이스가 제네릭 타입이기 때문에 작성된 유형입니다. 실제 사용하는 구체적인 타입은 구현 객체를 생성할 때 결정하게 되죠. (String 같은 타입)

 

기본적으로 객체를 추가할 때는 add( )를, 객체를 삭제할 때는 remove( )를 사용하게 됩니다. 아래 예시를 확인해 봅시다.

 

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

set.add("Swings");
set.add("Black Nut");

set.remove("Swings");

 

 

 

 


 

 

 

 

Set 컬렉션은 위에서도 설명했다시피 집합의 성격을 갖기 때문에, 인덱스를 통해 검색해서 객체를 호출하는 메서드가 존재하지 않습니다. 인덱스를 사용하는 방식 대신에, Iterator를 사용하게 됩니다. 

 

Iterator 역시 인터페이스입니다. 그래서 이를 사용하기 위해서는, Set 인터페이스를 구현한 객체의 iterator( ) 메서드를 실행하여 Iterator 인터페이스를 구현한 객체를 얻어야 합니다. 약간 내용이 헷갈릴 수 있으니, 아래의 예시를 참고해 보겠습니다. 

 

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

 

 

Iterator 인터페이스에 선언된 메서드들은 다음과 같습니다. 

 

Return Type Method Description
boolean hasNext( ) 가져올 객체가 있으면 true, 없으면 false를 리턴한다. 예를 들어 while( iterator.hasNext( ) ) 형태로 사용할 수 있다.
E next( ) 컬렉션에서 하나의 객체를 가져온다. 주로 이를 가져오기 전에, hasNext( )를 이용해 객체의 유무를 확인한다.
void remove( ) Set 컬렉션에서 객체를 제거한다.

 

 

메서드 정의와 설명만으로는, 어떻게 사용할지 잘 감이 잡히지 않는 것 같습니다. 간단한 예제를 통해서 살펴보도록 하겠습니다. 임의의 Set 컬렉션 set에 몇 개의 String 객체가 저장되었다고 가정해 보겠습니다. 

 

 

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

while( iterator.hasNext() ) {
	// String 객체 하나를 호출
    String str = iterator.next();
    System.out.println(str);
}

 

 

위와 같은 형식을 사용하게 되면, set에 저장된 객체의 수 만큼 루프가 발생해 작업을 수행하게 됩니다. 본 예제는 추후 학습해 볼 HashSet에서 실제로 다루게 되니, 참고하시기 바랍니다. 

 

참고로 Iterator를 사용하지 않더라도, 향상된 for문을 이용해 아래와 같이 반복을 수행할 수 있습니다. 

 

 

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

 

 

 

마지막으로 remove( ) 사용에 있어서 주의 사항을 살펴보겠습니다. 정리하면, remove( )는 Iterator 객체에서 호출되지만, 실제로 Set 컬렉션에서 삭제가 이루어집니다. 

 

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

while( iterator.hasNext() ) {
	// String 객체 하나를 호출
    String str = iterator.next();
    
    if( str.equals("Swings") ) {
    	// set에서 객체를 삭제한다.
        iterator.remove();
    }
}