null도 중복을 허용하지 않기 때문에 1개의 null만 저장
구현 클래스로 HashSet, LinkedHashSet, TreeSet이 있음

Set에 객체를 저장할 때 hash함수를 사용하여 처리 속도가 빠름
동일 객체 뿐 아니라 동등 객체도 중복하여 저장하지 않음
-> String, Integer 등 자바에서 제공하는 객체
모두 equals(), hashCode() 오버라이딩이 되어있는 상태
HashSet 객체 생성
Set<String> set = new HashSet<String>(); // 다형성 - 업캐스팅
set.add("네이버");
set.add("카카오");
set.add("라인");
set.add("쿠팡");
set.add("배달의민족");
set.add("당근마켓");
set.add("토스");
set.add("직방");
set.add("야놀자");
System.out.println(set);
[배달의민족, 당근마켓, 직방, 카카오, 네이버, 야놀자, 쿠팡, 라인, 토스]
-> HashSet 순서 유지 X 확인
중복 저장 확인
set.add("배달의민족");
set.add("배달의민족");
set.add("배달의민족");
set.add("배달의민족");
set.add("배달의민족");
System.out.println(set);
[배달의민족, 당근마켓, 직방, 카카오, 네이버, 야놀자, 쿠팡, 라인, 토스]
[배달의민족, 당근마켓, 직방, 카카오, 네이버, 야놀자, 쿠팡, 라인, 토스]
-> 중복 저장 X 확인
null : 참조하는 객체가 없음
null 도 중복 X 확인
set.add(null);
set.add(null);
set.add(null);
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
// [null, 배달의민족, 당근마켓, 직방, 카카오, 네이버, 야놀자, 쿠팡, 라인, 토스]
// null 1회 출력
System.out.println("set.size() : " + set.size());
set.size() : 10
System.out.println(set.remove("배달의민족"));
// true
System.out.println(set.remove("유플러스"));
// false
System.out.println("쿠팡 있는지 확인 : " + set.contains("쿠팡"));
// 쿠팡 있는지 확인 : true
System.out.println("삼성 있는지 확인 : " + set.contains("삼성"));
// 삼성 있는지 확인 : false
set.clear();
System.out.println(set);
// []
System.out.println(set.isEmpty());
// true
Set 에 저장된 요소(객체)를 꺼내는 방법
1. Iterator(반복자) 이용
2. List 로 변환
3. 향상된 for 문 이용
Set<String> set = new HashSet<String>();
set.add("몽쉘");
set.add("꼬북칩");
set.add("쿠크다스");
set.add("빈츠");
set.add("포카칩");
Iterator Set.iterator() :
현재 Set 을 순차 접근할 수 있는 Iterator 객체 반환
Iterator<String> it = set.iterator();
// boolean Iterator.hasNext() :
// 다음 순차 접근할 요소가 있으면 true, 없으면 false 반환
System.out.println("[1. Iterator]");
while(it.hasNext()) {
// 다음 요소가 있으면 반복, 없으면 멈춤
// E Iterator.next() : 다음 요소를 꺼내와 반환
String temp = it.next();
System.out.println(temp);
}
List<String> list = new ArrayList<String>(set);
for(int i = 0 ; i < list.size() ; i++) {
System.out.println(list.get(i));
}
for(String snack : set) {
System.out.println(snack);
}
hashCode, equals 오버라이딩 되어 있어야함
public void method3() {
Person p1 = new Person("홍길동", 25, '남');
Person p2 = new Person("홍길동", 25, '남');
Person p3 = new Person("홍길동", 30, '남');
Person p4 = new Person("김길순", 20, '여');
// Set 객체 생성 후 p1 ~ p4
Set<Person> personSet = new HashSet<Person>();
personSet.add(p1);
personSet.add(p2);
personSet.add(p3);
personSet.add(p4);
for(Person p : personSet) {
System.out.println(p);
}
}
Person 클래스
오버라이딩 hashCode, equals
단축키
ctrl shift s h
@Override
public int hashCode() {
return Objects.hash(age, gender, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
return age == other.age && gender == other.gender && Objects.equals(name, other.name);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
출력 결과
Person [name=홍길동, age=30, gender=남]
Person [name=김길순, age=20, gender=여]
Person [name=홍길동, age=25, gender=남]
HashSet과 거의 동일하지만 Set에 추가되는 순서를 유지한다는 점이 다름
Set<String> set = new LinkedHashSet<String>();
TreeSet : 이진 트리 구조를 이용해 객체를 저장하는 Set
-> 기본 오름차순 정렬
전제 조건 : 저장되는 객체는 Comparable 인터페이스 상속 필수
-> Integer (Wrapper 클래스) 는 Comparable 상속 되어있음
로또 번호 생성기
금액을 입력 받아(천원 단위)
1000원 당 1회씩 번호를 생성해서 List 에 저장한 후
생성 종료 시 한 번에 출력
금액 입력 : 3000 1회 : [11, 20, 34, 35, 42, 43] 2회 : [1, 12, 22, 33, 35, 44] 3회 : [5, 6, 24, 43, 44, 45]
public void lottoNumberGenerator() {
Scanner sc =new Scanner(System.in);
System.out.print("금액 입력 : ");
int amount = sc.nextInt();
Random random = new Random();
// 생성된 로또 번호 묶음(TreeSet)을 저장할 List
List<Set<Integer>> lottoList = new ArrayList<Set<Integer>>();
for(int i = 0 ; i < amount/1000 ; i++) {
// for 문 반복될 때마다 새로운 Set 객체를 생성
Set<Integer> lotto = new TreeSet<Integer>();
while(lotto.size() < 6) {
lotto.add( random.nextInt(45) + 1 ); // 1 ~ 45 사이 난수 추가
}
lottoList.add(lotto); // List 에 Set 추가(담기)
// -> 반복 시 마다
// List 각 인덱스에 서로 다른 Set 참조 주소가 저장됨
}
// 출력용 반복문
for(int i = 0 ; i < lottoList.size() ; i++) {
System.out.println((i+1) + "회 : " + lottoList.get(i));
}
}
출력 결과
금액 입력 : 10000
1회 : [1, 4, 8, 21, 29, 44]
2회 : [3, 11, 15, 23, 34, 41]
3회 : [6, 11, 12, 20, 23, 41]
4회 : [2, 22, 23, 25, 30, 33]
5회 : [19, 24, 26, 27, 39, 45]
6회 : [1, 7, 11, 15, 16, 35]
7회 : [17, 22, 24, 27, 33, 37]
8회 : [2, 3, 8, 19, 25, 36]
9회 : [3, 11, 20, 30, 35, 37]
10회 : [2, 13, 16, 20, 25, 31]