List는 저장 순서를 유지하지만,
Set은 저장 순서가 유지되지 않는다
: 객체의 중복저장 불가
-> 동일 값, 동등 객체의 중복 저장 x
: 하나의 null은 저장 가능
: 순서가 유지되지 않기 때문에 인덱스로 꺼내올 수 없음. 그래서 사용하는 것이 이터레이터!
-Set은 인덱스로 관리하지 않기 때문에, 인덱스를 매개값으로 갖는 메소드가 없다.
-E라는 타입 파라미터는 Set이 인터페이스가 제네릭 타입이기 때문이다.
다음은 set컬렉션에 객체를 추가 삭제하는 모습이다.
// Set에 자료 값 입력하기
// Integer 형식
set.add(10);
// String 형식
set.add("Java");
// boolean 형식
set.add(true);
// 객체(클래스)
set.add(new Student());
// 중복값을 넣으려 하면 오류는 안나지만 저장이 안된다
set.add(10);
// 값 삭제하기
set.remove(true);
Iterator 인터페이스에 선언된 메소드는 아래와 같다
Set은 인덱스로 객체를 검색해서 가져오는 메소드가 없다. 대신, 전체 객체를 하나씩 가져오는 반복자(=Iterator)를 제공하는 것이다
// 반복자 메소드 호출
Iterator 변수명 = set객체명.iterator();
// 가져올 객체가 있을때까지 (true 리턴받아) 반복
// =저장된 객체 수만큼 반복한다
while(변수명.hasNext()) {
System.out.println(변수명.next());
}
Set 인터페이스의 구현 클래스
// 생성자 호출
Set<E> 변수명 = new HashSet<E>();
만약 문자열을 HashSet에 저장할 경우, 같은 문자열을 갖는 String 객체는 동등한 객체로 간주되고 다른 문자열을 갖는 String 객체는 다른 객체로 단주된다.
HashSet을 생성자 호출 해준 뒤 값을 입력해주고 .add
현재 사이즈를 확인 해본다 .size
자료를 하나씩 출력하기 위해 Iterator
값 지워주기 위해 .remove
저장된 객체를 모두 삭제하기 위해 .clear()
public class HashSetEx {
public static void main(String[] args) {
HashSet set = new HashSet();
// Set에 자료 값 입력하기
set.add(10);
set.add("Java");
set.add(true);
set.add(new Student());
// 중복값을 넣으려 하면 오류는 안나지만 저장이 안된다
set.add(10);
// 사이즈를 출력해보면 5개를 입력했음에도 4개만 저장되어있는 걸 확인
// 왜냐면 중복값은 새로운 값으로 받아들이지 않기 때문에
System.out.println("현재 set의 사이즈 : " + set.size());
System.out.println();
// 자료를 하나씩 출력하기
// 입력 순서와 상관없이 값이 튀어나오는 모습을 볼 수 있다
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
System.out.println();
// 값 지워주기
set.remove(true);
// 확인
System.out.println("값 하나를 지워준 뒤 set의 사이즈 : " + set.size());
Iterator it2 = set.iterator();
while(it2.hasNext()) {
System.out.println(it2.next());
}
System.out.println();
// 저장된 객체 모두 삭제
set.clear();
System.out.println("clear한 후 set의 사이즈 : " + set.size());
}
}
class Student{
@Override
public String toString() {
return "Student 클래스";
}
}
실행 모습
생성자 호출시 타입을 지정 안해줬기 때문에 다양한 값들이 들어갈 수 있었지만, 지정해주는 것이 좋다.
생성자 호출시 타입을 지정해서 사용하는 모습
Set<String> set = new HashSet<String>();
// 값 저장
// 중복 값 입력시 저장 되는지 확인
set.add("Java");
set.add("JDBC");
set.add("Servlet/JSP");
set.add("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 비어있습니다
인스턴스가 달라도 이름과 나이가 동일하다면, 동일 객체로 간주하여 중복 저장되지 않도록 하기 위해서..
// 클래스 멤버를 집어넣어 중복으로 set에 들어가는지 확인
public class HashSetEx2 {
public static void main(String[] args) {
// Set을 만드는데 리턴타입은 Member로 한다
Set<Member> set = new HashSet<Member>();
Member m1 = new Member("홍길동", 13, "123");
Member m2 = new Member("김자바", 20, "312");
Member m3 = new Member("이곡길", 25, "132");
Member m4 = new Member("홍길동", 13, "123");
set.add(m1);
set.add(m2);
set.add(m3);
set.add(m4);
// 주소를 받아들이고 있기 때문에
// 동일 객체도 다른 값으로 판단
// 그래서 Member에서 equals 처리를 해줘야 한다.
System.out.println("set에 들어간 자료 개수 : " + set.size());
System.out.println();
System.out.println("[해쉬코드 값 출력]");
// 해쉬코드 출력
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
System.out.println(m3.hashCode());
System.out.println(m4.hashCode());
System.out.println();
System.out.println("[equals 비교]");
// equal 값 출력
System.out.println(m1.equals(m2));
System.out.println(m1.equals(m4));
}
}
class Member {
String name;
String tel;
int age;
public Member(String name, int age, String tel) {
this.name = name;
this.age = age;
this.tel = tel;
}
// 값이 다 같으면 동일한 hashCode를 리턴해준다
@Override
public int hashCode() {
return name.hashCode() + age + tel.hashCode();
}
// name과 age값이 같이면 true를 리턴하는 곳
@Override
public boolean equals(Object obj) {
if(obj instanceof Member) {
Member member = (Member) obj;
return member.name.equals(name) && (member.age == age) && member.tel.equals(tel);
} else {
return false;
}
}
}
실행 모습
학생 객체
1반 1번 100
1반 2번 89
1반 2번 90
1반 1번 80
출력
1반 1번 180점
1반 2번 179점
전체 코드
public class HashSetEx_Test {
public static void main(String[] args) {
Set<Student1> set = new HashSet<Student1>();
Student1 s1 = new Student1(1, 1, 100);
Student1 s2 = new Student1(1, 2, 89);
Student1 s3 = new Student1(1, 2, 90);
Student1 s4 = new Student1(1, 1, 80);
if (s1.equals(s2)) {
s1.hap = s1.hap + s1.jumsu + s2.jumsu;
}
if (s1.equals(s3)) {
s1.hap = s1.hap + s1.jumsu + s3.jumsu;
}
if (s1.equals(s4)) {
s1.hap = s1.hap + s1.jumsu + s4.jumsu;
}
if (s2.equals(s3)) {
s2.hap = s2.hap + s2.jumsu + s3.jumsu;
}
if (s2.equals(s4)) {
s2.hap = s2.hap + s2.jumsu + s4.jumsu;
}
if (s3.equals(s4)) {
s3.hap = s3.hap + s3.jumsu + s4.jumsu;
}
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
Iterator<Student1> it = set.iterator();
while (it.hasNext()) {
Student1 s = it.next();
System.out.println(s.ban + "반 " + s.bun + "번 " + s.hap + "점 ");
}
}
}
class Student1 {
int ban;
int bun;
int jumsu;
int hap;
public Student1(int ban, int bun, int jumsu) {
this.ban = ban;
this.bun = bun;
this.jumsu = jumsu;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return ban + bun;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Student1) {
Student1 s = (Student1) obj;
if (ban == s.ban && bun == s.bun)
return true;
}
return false;
}
}
실행 모습
1반 1번 180점 1반 2번 179점