List 컬렉션은 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지 않는다. 또한 객체를 중복해서 저장할 수 없고, 하나의 null만 저장할 수 있다.
Set 컬렉션은 수학의 집합에 비유될 수 있다. 집합은 순서와 상관없고 중복이 허용되지 않기 때문이다. 그리고 들어갈 때의 순서와 나올때의 순서가 다르다!
다음은 Set 컬렉션에서 공통적으로 사용 가능한 Set 인터페이스의 메소드들이다. 인덱스로 관리하지 않기 때문에 인덱스를 매개 값으로 갖는 메소드가 없다.
기능 |
메소드 |
설명 |
객체 추가 |
boolean add(E e) |
주어진 객체를 저장, 객체가 성공적으로 저장되면 true를 리턴하고 중복 객체면 false를 리턴 |
객체 검색 |
boolean contain(Object o) |
주어진 객체가 저장되어 있는지 여부 |
isEmpty( ) |
컬렉션이 비어 있는지 조사 | |
Iterator<E> iterator( ) |
저장된 객체를 한 번씩 가져오는 반복자 리턴 | |
int size( ) |
저장되어 있는 전체 객체 수 리턴 | |
객체 삭제 |
void clear( ) |
저장된 모든 객체를 삭제 |
boolean remove(Object o) |
주어진 객체를 삭제 |
E 라는 타입은 Set 인터페이스가 제네릭 타입이기 때문이다. 구체적인 타입은 구현 객체를 생성할 때 결정된다.
객체 추가는 add() 메소드를 사용하고, 객체 삭제는 remove() 메소드를 사용한다.
1 2 3 4 |
Set<String> set = ..; set.add("홍길동"); set.add("김길동"); //객체 추가 set.remove("홍길동"); //객체삭제 |
위와 같이 사용할 수 있다.
Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없다.
(인덱스로 저장되지 않기 때문!!)
대신, 전체 객체를 대상으로 한번씩 반복해서 가져오는 반복자(Iterator)를 제공한다. 반복자는 Iterator 인터페이스를 구현한 객체를 말하는데 iterator() 메소드를 호출하면 얻을 수 있다.
1 2 |
Set<String> set = ..; Iterator<String> itr = set.iterator(); |
위와 같이 반복자를 얻고 아래 있는 메소드를 이용할 수 있다.
리턴 타입 |
메소드명 |
설명 |
Boolean |
hasNext( ) |
가져올 객체가 있으면 true를 리턴하고 없으면 false |
E |
next( ) |
컬렉션에서 하나의 객체를 가져온다. |
void |
remove( ) |
Set 컬렉션에서 객체를 제거한다. |
Iterator에서 하나의 객체를 가져올 때는 next() 메소드를 사용한다. 이 메소드를 사용하기 전에 hasNext() 메소드를 통해 가져올 객체가 있는지 확인하는 것이 좋다.
다음과 같이 말이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Set<String> set = ..; Iterator<String> itr = set.iterator(); while(itr.hasNext()) { //String 객체 하나를 가져옴 String str = iterator.next(); } //또는 for문으로 for(String str : set) { } Colored by Color Scripter |
이 Set 컬렉션에서 대표적인 것이 HashSet이다.
객체를 순서 없이 저장하고 동일한 객체를 중복 저장하지 않는다. HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 메소드를 호출해서 해시코드를 얻어낸다. 그리고 이미 저장되어 있는 객체들의 해시코드와 비교한다. 만약 동이한 해시코드가 있다면 다시 equals() 메소드로 두 객체를 비교해서 true가 나오면 동일한 객체로 판단하고 중복 저장을 하지 않는다.
다음 예제를 보면서 확인을 해보자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class HashEx { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("java"); set.add("jdbc"); set.add("servlet"); set.add("java"); //java는 한번만 저장됨 int size = set.size(); System.out.println("총 개수 : "+size); Iterator<String> itr = set.iterator(); while(itr.hasNext()) { System.out.println(itr.next()); } } } Colored by Color Scripter |
와 같이 된다.
그리고 사용자 정의 클래스인 Member를 만들고 hashCode()와 equals() 메소드를 오버라이딩 하여 사용자 정의를 할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package study_myself_9_from_728; import java.util.*; class Member{ public String name; public int age; public Member(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj) { if(obj instanceof Member) { Member member = (Member) obj; return member.name.equals(name) && (member.age == age); } else { return false; } } public int hashCode() { return name.hashCode() + age; //String의 hashCode이용 } } public class HashEx2 { public static void main(String[] args) { Set<Member> set = new HashSet<Member>(); set.add(new Member("홍길동", 30)); set.add(new Member("홍길동", 30)); //인스턴스는 다르지만 내부 데이터가 동일하므로 객체 1개만 저장 System.out.println("총 객체수 : "+set.size()); } } Colored by Color Scripter |
인스턴스가 달라도 내부 데이터가 동일해서 1개만 저장이 된다.
이런식으로 사용할 수 있다.
'java' 카테고리의 다른 글
자바 컬렉션 프레임워크(Collection Framework)Map 컬렉션(HashMap, Hashtable) (0) | 2017.08.21 |
---|---|
자바 2차원 배열 여러가지 예제 (0) | 2017.08.21 |
자바 컬렉션 프레임워크(Collection Framework)소개 및 List 컬렉션(Array List, Vector, LinkedList) (0) | 2017.08.18 |
자바 배열로 날짜(D-day) 계산해보기(2017년 기준) (0) | 2017.08.18 |
자바 로또(lotto) 만들어 보기(배열, Hash) (0) | 2017.08.18 |