20/11/16

아라·2020년 11월 17일
0

국비교육

목록 보기
25/30

Set

순서가 없는 배열. 방번호(index)가 없음. 중복값을 가질 수 없음. HashSet, TreeSet.

HashSet<String> set=new HashSet<String>();
// 요소 추가하기
System.out.println(set.add("사과"));
set.add("딸기");
set.add("바나나");
System.out.println(set.add("사과")); // 사과는 이미 들어가있기 때문에 false 반환.
set.add("바나나");

// 요소 개수
System.out.println(set.size());

// toString()
System.out.println(set);

// 개별 요소 탐색 -> 불가능! (******) 방번호가 없기 때문에!
//		System.out.println(set.get(0));
// 그래서 요소 탐색을 사용하려면 iterator를 사용할 것!

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

while(iter.hasNext()) {
	System.out.println(iter.next());
}

// 로또 번호 6개(1~45)
Random rnd=new Random();

ArrayList<Integer> lotto=new ArrayList<Integer>();
for (int i=0; i<6;i++) {
	int n=rnd.nextInt(45)+1;

	// 검증
	boolean flag=false;
	for(int j=0;j<i;j++) {
		if (n==lotto.get(j)) {
			flag=true;
			break;
		}else {
			flag=false;
		}
	}
	if (flag) {
		i--;
	}else {
		lotto.add(n);
	}
			
}
Collections.sort(lotto);
System.out.println(lotto);

// Set 구현
HashSet<Integer> lotto2=new HashSet<Integer>();
while(lotto2.size()<6) {
	lotto2.add(rnd.nextInt(45)+1);
}
System.out.println(lotto2);


//행사 -> 경품
//1. 중복 당첨 가능 > List
//2. 중복 당첨 불가능 > Set

ArrayList<String> box = new ArrayList<String>(); //응모권 상자

box.add("홍길동");
box.add("아무개");
box.add("유재석");
box.add("강호동");
box.add("박명수");
box.add("정준하");
box.add("하하");
box.add("김영철");

//추첨 명단(3명)
ArrayList<String> result1 = new ArrayList<String>();
HashSet<String> result2 = new HashSet<String>();


while (result1.size() < 3) {
	result1.add(box.get(rnd.nextInt(box.size())));
}

while (result2.size() < 3) {
	result2.add(box.get(rnd.nextInt(box.size())));
}

System.out.println();
System.out.println(result1);
System.out.println(result2);
// 단일값 집합(값형, 문자열)
HashSet<Integer> set1=new HashSet<Integer>();

set1.add(100);
set1.add(200);
set1.add(300);
set1.add(100);

System.out.println(set1);
// 복합값 집합(객체)
// Set이 객체를 저장하는 용도로 사용될 때는
// 동일 객체 비교를 hashCode()를 사용해서 비교

// 객체가 들어가는 Set에서 객체의 상태가 동일하면 같은 객체로 취급하고 싶다.
// -> 해당 객체의 클래스에서 hashCode()를 재정의한다.
HashSet<Person> set2=new HashSet<Person>();
set2.add(new Person("홍길동", 20));
set2.add(new Person("아무개", 22));
set2.add(new Person("하하하", 25));

set2.add(new Person("홍길동", 20));
// HashSet은 단일값일 경우 중복을 제외하지만,
// 객체인 경우 주소값 비교를 하기 때문에 중복값을 넣을 수 있다. 동명이인으로 처리.
// 실제 출력결과 : [{name=아무개, age=22}, {name=홍길동, age=20}, {name=홍길동, age=20}, {name=하하하, age=25}]

System.out.println(set2);

// 같은 객체를 찾아내기! -> 해시코드로!
Person p1=new Person("홍길동", 20);
Person p2=new Person("아무개", 22);

// com.test.collection2.Person@3039 -> 3039는 해시코드(12345, 10진수)의 return값(16진수)
// 자료형@해시코드(메모리주소값)
// p1 주소값 : com.test.collection2.Person@5c647e05 // 실제 존재하는 곳
// p2 주소값 : com.test.collection2.Person@33909752
// 실제 존재하는 곳은 5c647e05와 33909752.
// 주소값을 적절히 조절하면 다른 값을 같다고 할 수도 있고,
// 같은 값을 다르다고 할 수도 있다.
// 객체 비교할 때 HashCode 이용.
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p1==p2);
System.out.println(p1.equals(p2));

// 사실 문자열은 재사용! 메모리 낭비를 막기 위해.
// "홍길동"이라는 공간이 s1, s2에 재사용되는 것
// 문자열은 불변이다. (Immutable) -> 고칠 수 없다
// "홍길동"+"님" -> "홍길동님"으로 보이지만
// 사실 메모리를 늘리거나 줄일 수 없다.

// Stack : 질서정연 <-> Heap : 자유분방
// 이렇게 생각할 것.
// 크기가 가변이면 Heap영역에 생긴다.

String s1="홍길동";
String s2="홍길동";
String s3="홍";
s3=s3+"길동";

System.out.println(s1==s2);
System.out.println(s1.equals(s2));
System.out.println(s1==s3);
System.out.println(s1.equals(s3));

System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
// 둘다 54150062

Person p3=new Person("호호호", 28);
Person p4=new Person("호호호", 28);

// 해시코드를 재정의하고, equals도 오버라이딩하면
// 아래의 결과는 true가 나온다.
System.out.println(p3.equals(p4));

class Person{
	
	public String name;
	public int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "{name=" + name + ", age=" + age + "}";
	}
	
	@Override
	public int hashCode() {
		// "홍길동20" -> 12345
		// "아무개22" -> 23423
		// "홍길동20" -> 12345
		return (this.name+this.age).hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		// 참조 주소값의 비교 -> 상태값 비교
		Person p=(Person)obj;
		return this.name.equals(p.name) && this.age==p.age;
	}
}

TreeSet

Tree구조를 가지는 Set. 중복값X, 순서X, 정렬X. 이진트리구조를 기반으로 자동 정렬이 되는 Set. 정렬된 상태에서의 Set이 필요할 때 사용. 검색에 장점!

TreeSet<Integer> set=new TreeSet<Integer>();
		
set.add(5);
set.add(3);
set.add(1);
set.add(2);
set.add(7);
set.add(9);
set.add(6);
set.add(4);
set.add(8);

System.out.println(set.size());
System.out.println(set);

Iterator iter=set.iterator();

while(iter.hasNext()) {
	System.out.println(iter.next());
}

// TreeSet 목적
// 1. 정렬(중복값 없는)
// 2. 부분 검색 능함(*****)

System.out.println(set.first());
System.out.println(set.last());
System.out.println(set.headSet(5)); // 5는 방번호 아님!!! "5"를 만날 때까지 가져오는 것.
System.out.println(set.tailSet(5));
System.out.println(set.subSet(3, 7)); // "3" 등장에서부터 "7" 등장까지.("7"은 미포함)

// 중복값 없는 집합 -> Set -> HashSet vs TreeSet?
// 1. 뭐가 뭔지 잘 모름 -> HashSet
// 2. 범위 검색 필요 -> TreeSet
// 3. 나머지 -> HashSet

// 중복값 있는 집합 -> List vs Map?
// 1. 뭐가 뭔지 잘 모름 -> ArrayList
// 2. 첨자(index) O -> List
//  2-1. 조작이 심하다 -> LinkedList
//  2-2. 조작이 덜하다 -> ArrayList
//  2-3. 선입선출 -> Queue(LinkedList)
//  2-4. 후입선출 -> Stack
// 3. 키 사용 -> HashMap
//  3-1. 범위 검색 -> TreeMap
//  3-2. 나머지 -> HashMap

// List -> ArrayList
// Map -> HashMap
// Set -> HashSet

0개의 댓글