List 컬렉션은 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지는 않습니다. 또한 객체를 중복 저장할 수 없고
하나의 null만 저장할 수 있어 set 컬렉션은 수학의 집합에 비유될 수 있습니다.
사진 출처 : JAVA EE: Java : Collection Framework : Hierarchy(Iterable, Collection) (ramj2ee.blogspot.com)
Set컬렉션에는
HashSet, LinkedHashSet, TreeSet 등이 있습니다.
위에 메소드는 Set 컬렉션에서 공통적으로 사용 가능한 Set 인퍼에이스의 메서드입니다. 인덱스로 관리하지 않기 때문에 매개 값으로 갖는 메서드가 없습니다.
Set<String> set = ...;
set.add("홍길동"); // 객체를 추가합니다.
set.add("홍길순");
set.remove("홍길동"); // 객체를 삭제합니다.
Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없는데 대신 전체 객체를 대상으로 한 번씩 반복해서 가져오는
반복자(Iterator)를 제공합니다.
반복자는 Iterator 인터페이스를 구현한 객체인데 Iterator() 메서드를 호출하면 얻을 수 있습니다.
Set<String> set = ....;
Iterator<String> iterator = set.iterator();
리턴 타입 | 메소드명 | 설명 |
boolean | hasNext() | 가져올 객체가 있으면 true을 리턴 없으면 false를 리턴합니다. |
E | next() | 컬렉션에서 하나의 객체를 가져옵니다. |
void | remove() | Set 컬렉션에서 객체를 제거합니다. |
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컬렉션에서 Iterator의 next() 메소드로 가져온 객체를 제거하고 싶다면 remove() 메서드를 호출하면 됩니다.
Iterator의 메소드이지만 실제 Set 컬렉션에서 객체가 됩니다.
while(iterator.hasNext()) {
String str = iterator.next();
if(str.equals("홍길동")) {
iterator.remove();
// Set 컬렉션에서 홍길동 제거
}
}
HashSet
HashSet은 Set 인터페이스의 구현 클래스이고 HashSet을 생성하기 위해서는 밑에처럼 기본 생성자를 호출하면 됩니다.
Set<E> set = new HashSet<E>();
타입 파라미터 E에는 컬렉션에서 저장할 객체 타입을 지정하면 됩니다. 예를 들어서 String 객체를 저장하는 HashSet은
Set<String> set = new HashSet<String>();
이렇게 생성할 수 있습니다.
HashSet은 객체들을 순서 없이 저장하고 동일한 객체는 저장 하지 않습니다. HashSet이 판단하는 동일한 객체는 꼭 같은 인스턴스를 뜻하지 않고 HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 메서드를 호출해서 해시 코드를 얻어냅니다. 그리고 이미 저장되어 있는 객체들의 해시 코드를 비교하고 만약 동일한 해시 코드가 있다면 equlas() 메서드로 두 객체를 비교해보고 true가 나오면 동일한 객체로 판단하고 중복 저장을 하지 않습니다.
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Ex5 {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("Java");
set.add("Spring");
set.add("JSP");
set.add("Java");
set.add("phyton");
// Java는 중복이라 하나의 객체만 저장될것임
int size = set.size(); // 저장된 객체 수 얻기
System.out.println("set의 사이즈 : " + set.size());
Iterator<String> it = set.iterator(); // 반복자 생성
while(it.hasNext()) { // it의 객체수만큼 반복한다
String element = it.next(); //한개의 객체만 들고온다.
System.out.println("\t"+element);
}
}
}
코드 실행시 Java 객체 하나가 중복이라 저장되지 않는 것을 확인할 수 있다.
다시 저장된값을 삭제하는 방법
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Ex5 {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("Java");
set.add("Spring");
set.add("JSP");
set.add("Java");
set.add("phyton");
// Java는 중복이라 하나의 객체만 저장될것임
int size = set.size(); // 저장된 객체 수 얻기
System.out.println("set의 사이즈 : " + set.size());
Iterator<String> it = set.iterator(); // 반복자 생성
while(it.hasNext()) { // it의 객체수만큼 반복한다
String element = it.next(); //한개의 객체만 들고온다.
System.out.println("\t"+element);
}
========================================================================
set.remove("JSP"); // 한개의 객체 삭제
set.remove("phyton"); // 한개의 객체 삭제
System.out.println("총 객체수 : " + set.size());
// 저장된 객체수 얻기
it = set.iterator(); // 반복자 얻기
while(it.hasNext()) { // it의 객체수만큼 반복
String element = it.next(); //한개의 객체만 들고온다.
System.out.println("\t"+element);
}
set.clear(); // 모든 객체를 제거하고 비웁니다.
if(set.isEmpty()) {
System.out.println("비어 있습니다.");
}
}
}
출력 결과.
인스턴스를 사용하여 이름과 나이가 동일한 객체 추가 시 중복 저장 안 되는지 확인해보자
package Ex00;
public class Member {
// 필드생성
public String name;
public int age;
// 생성자
public Member(String name, int age) {
this.name = name;
this.age =age;
}
@Override
public boolean equals(Object obj) {
// name과 age가 값이 같으면 true를반환
if(obj instanceof Member) {
// instanceof 연산자를 이용
// object가 type이거나 type을 상속받는 클래스라면 true리턴할것임
Member member = (Member) obj;
return member.name.equals(name) && (member.age == age);
}else {
return false;
}
}
@Override
public int hashCode() { // name과 age가 같으면 동일한 hashcode를 리턴해준다.
return name.hashCode() + age;
} // String의 hashCode() 이용한다.
}
먼저 hashCode()와 equlas() 메서드를 재정의 해준다
다음 데이터 저장이 한 개만 되는지 확인해본다.
package Ex00;
import java.util.HashSet;
import java.util.Set;
public class HashSetEx {
public static void main(String[] args) {
Set<Member> set = new HashSet<Member>();
set.add(new Member("홍길동",15));
set.add(new Member("홍길동",15));
// 인스턴스는 다르지만 내부 데이터가 동일하여 한가지만 등록될것임
System.out.println("총 객체수 : " + set.size());
}
}
실행결과 객체수 1개만 등록되었습니다.
'JAVA' 카테고리의 다른 글
멀티 스레드 (0) | 2022.06.02 |
---|---|
Map 컬렉션 (0) | 2022.05.31 |
컬렉션 프레임워크 LinkedList (0) | 2022.05.30 |
컬렉션 프레임워크 Vector (0) | 2022.05.30 |
컬렉션 프레임워크 ArrayList (0) | 2022.05.30 |