- 가변 매개변수
예제)
package ex1;
public class Ex1_0625 {
public static void main(String[] args) {
showAll("Box");
showAll("Box", "Toy");
showAll("Box", "Toy", "Apple");
}
//가변매개변수
private static void showAll(String...vargs) {
System.out.println("len = "+vargs.length);
for(String s:vargs) {
System.out.println(s+"\t");
}
System.out.println();
}
}
ㄴ 해당 예제의 메인 메서드의 인스턴스를 배열로 바꿔보자
예제_변경)
package ex1;
public class Ex1_0625 {
public static void main(String[] args) {
showAll(new String[] {"Box"});
showAll(new String[] {"Box", "Toy"});
showAll(new String[] {"Box", "Toy", "Apple"});
}
//가변매개변수
private static void showAll(String...vargs) {
System.out.println("len = "+vargs.length);
for(String s:vargs) {
System.out.println(s+"\t");
}
System.out.println();
}
}
- Math class
- math class
- 수학계산에 유용한 메서드로 구성되어 있고, 메서드가 모두 Static으로 정의되어 있다.
- 단 대부분의 메서드가 육십분법인 디그리 단위가 아닌 라디안 단위로 정의되어 있다.
- random number(난수)의 생성
- 난수를 반환하는 메서드
- 예전에는 Math.random을 많이 사용했지만 요즘은 Random class를 많이 사용한다.
boolean nextBoolean() //boolean형 난수 반환
int nextInt() //int형 난수 반환
long nextLong() //long형 난수 반환
int nextInt(int n) //0이상 n미만의 범위 내에 있는 int형 난수 반환
float nextFloat() //0.0이상 1.0미만의 float형 난수 반환
double nextDouble() //0.0이상 1.0미만의 double형 난수 반환
예제 1)
package ex1;
import java.util.Random;
public class Ex2_0625 {
public static void main(String[] args) {
Random r = new Random();
for(int i=0;i<10;i++) {
System.out.println(r.nextInt(100));
// 랜덤으로 0과 100사이의 난수를 10번 출력
}
}
}
예제 1-1)
package ex1;
import java.util.Random;
public class Ex2_0625 {
public static void main(String[] args) {
Random r = new Random(9); //이처럼 9을 넣으면 고정된 수가 나오게 된다.
//왜?
for(int i=0;i<10;i++) {
System.out.println(r.nextInt(46)+1);
}
}
}
ㄴ 9라는 숫자를 정하는 시드가 숫자를 정하는 패턴을 정하게 되어 고정되는 수가 나오게 된다.
ㄴ 그렇다면 어떻게 시드를 다르게 해야 할까
예제 1-2)
package ex1;
import java.util.Random;
public class Ex2_0625 {
public static void main(String[] args) {
Random r = new Random();
// Random() 내부에서 아래와 같이 씨앗을 심는다.
r.setSeed(System.currentTimeMillis()); //매번 씨드를 다르게 해서 수를 다르게 해야한다.
for(int i=0;i<10;i++) { //i는 몇번 돌릴지 정하는 인스턴스
System.out.println(r.nextInt(46)+1);
// 랜덤으로 0과 100사이의 난수를 10번 출력
}
}
ㄴ System.currentTimeMillis() : 1970년 1월 1일부터 경과한 시간을 long 값으로 리턴하며, 밀리세컨드 그러니까 1/1000초 값을 리턴한다. 이를 이용해 현재 시간을 구할 수 있다.
ㄴ 만약에 랜덤을 돌리는 시간을 측정하고 싶으면 다음과 같이 한다.
예제 1-3)
package ex1;
import java.util.Random;
public class Ex2_0625 {
public static void main(String[] args) {
Random r = new Random();
// Random() 내부에서 아래와 같이 씨앗을 심는다.
// r.setSeed(System.currentTimeMillis()); //매번 씨드를 다르게 해서 수를 다르게 해야한다.
long start = System.currentTimeMillis();
for(int i=0;i<10;i++) { //i는 몇번 돌릴지 정하는 인스턴스
System.out.println(r.nextInt(46)+1);
// 랜덤으로 0과 100사이의 난수를 10번 출력
}
long end = System.currentTimeMillis();
System.out.println("처리 시간은 : "+(end-start)/1000.0 +"초");
//0.001초 소요
}
}
ㄴ 만약에 로또라면
예시_로또
package ex1;
public class Lotto {
private int[] number = new int[6];
// 1게임에서 6개 숫자만 뽑을 경우
// private int[][] number = new int[games][6];
// private int games;
// 여러게임에서 6개 숫자를 각각 뽑고 싶은 경우
// 생성자 메서드
// 난수를 배열에 저장 메서드(중복 숫자 제거 필요) **
// 배열 출력 메서드
// 숫자 정렬 메서드(필요하다면) -> Array 클래스 활용 정렬
}
// 예시
// 게임수 입력 : n
// 4,5,8,2,6,1
// .
// .
// . etc.(n)
예제_로또_나의 코딩) 꼭 해보기
3. Math.random();
- Math클래스에 정의된 난수 발생함수 p.s 난수란 ;정의된 범위 내에서 무작위로 추출된 수를 일컫는다. 난수는 누구라도 그 다음에 나올 값을 확신할 수 없어야 한다.
- 0.0과 1.0 미만 사이의 double 값을 반환한다.
예제)
package ex1;
public class Ex3_0625 {
public static void main(String [] args) {
int rNum = (int)(Math.random()*10+1);
// (0.0 ~ 0.9*10)+1 = 0 ~ 9.9...
}
}
문제 1 풀어보기
키보드로부터 두 정수를 입력 받는다. 그 수를 10과 100사이에 존재하는 난수 10개를 생성하여 출력하라.
스플릿 다시 보기(split)
- 문자열 토큰(Token)의 구분
ㄴ while에서 토큰의 유무를 확인하고 있으면 nextToken으로 출력된다.
+ Date, Calendar class
1. Date class
- JDK1.0부터 Date 클래스가 사용되었으나 JDK1.1부터 보다 향상된 Calendar가 추가되었다. 그래서 가능하면 Date보다는 Calendar를 사용하자.
- Date 클래스의 생성자나 메서드의 대부분은 Deprecated(중요도가 떨어져 더 이상 사용되지 않고 앞으로는 사라지게) 되었고, Date 객체의 정보는 toString()을 이용해서 출력하는 방식만이 주로 이용된다.
Date class 예제)
package practice;
import java.util.Date;
public class DateTest {
public static void main(String [] args) {
Date date1 = new Date();
System.out.println("year : "+date1.getYear());
System.out.println("month : "+date1.getMonth());
System.out.println("date : "+date1.getDate());
System.out.println(date1);
}
}// class end
Date class 결과)
year : 121
month : 5
date : 25
Fri Jun 25 16:33:44 KST 2021
2. Calendar class
예시)
// 기본적으로 현재 날짜와 시간으로 설정된다.
Calendar today = Calendar.getInstance();
System.out.println("이 해의 년도 : "+today.get(Calendar.YEAR));
System.out.println("월(1~12) : "+(today.get(Calendar.MONTH)+1));
System.out.println("이 해의 몇 째 주 : "+today.get(Calendar.WEEK_OF_YEAR));
System.out.println("이 달의 몇 째 주 : "+today.get(Calendar.WEEK_OF_MONTH));
// DATE와 DAY_OF_MONTH는 같다.
System.out.println("이 달의 몇 일 : "+today.get(Calendar.DATE));
System.out.println("이 달의 몇 일 : "+today.get(Calendar.DAY_OF_MONTH));
System.out.println("이 해의 몇 일 : "+today.get(Calendar.DAY_OF_YEAR));
System.out.println("요일(1-7, 1:일요일) : "+today.get(Calendar.DAY_OF_WEEK));
System.out.println("이 달의 몇째 요일 : "+today.get(Calendar.DAY_OF_WEEK_IN_MONTH));
System.out.println("오전_오후(0 : 오전, 1 : 오후"+today.get(Calendar.AM_PM));
System.out.println("시간(0~11) : "+today.get(Calendar.AM));
System.out.println("시간(12~23) : "+today.get(Calendar.PM));
System.out.println("분(0~59) : "+today.get(Calendar.MINUTE));
System.out.println("초(0~59) : "+today.get(Calendar.SECOND));
System.out.println("1000분의 1초(0~999) : "+today.get(Calendar.MILLISECOND));
// 천분의 1초를 시간으로 표시하기 위해 3600000으로 나누었다.
System.out.println("TimeZone(-12~+12) : "+(today.get(Calendar.ZONE_OFFSET)/(60*60*1000)));
System.out.println("이 달의 마지막 날 : "+today.getActualMaximum(Calendar.DATE)));
// 이 달의 마지막 일을 찾는다.
결과)
이 해의 년도 : 2021
월(1~12) : 6
이 해의 몇 째 주 : 26
이 달의 몇 째 주 : 4
이 달의 몇 일 : 25
이 달의 몇 일 : 25
이 해의 몇 일 : 176
요일(1-7, 1:일요일) : 6
이 달의 몇째 요일 : 4
오전_오후(0 : 오전, 1 : 오후1
시간(0~11) : 1
시간(12~23) : 2021
분(0~59) : 56
초(0~59) : 18
1000분의 1초(0~999) : 261
TimeZone(-12~+12) : 9
이 달의 마지막 날 : 30
+ 열거형(enum)
1. 인터페이스 기반의 상수의 문제점
- 각 인터페이스의 상수가 중복되어서 문제가 발생한다.
예제)
package practice;
public interface Animal {
int DOG=1, CAT=2, BEAR=3;
}
package practice;
public interface Person {
int MAN=1, WOMAN=2, BABY=4;
}
package practice;
public class NonSageInterfaceConst {
public static void main(String[] args) {
whoAreYou(Person.MAN);
whoAreYou(Animal.DOG);
int myFriend = Person.WOMAN;
if (myFriend == Animal.CAT) {
System.out.println("고양이 입니다.");
} else {
System.out.println("고양이가 아닙니다.");
}
}
public static void whoAreYou(int man) {
switch (man) {
case Person.MAN:
System.out.println("남자 손님입니다.");
break;
case Person.WOMAN:
System.out.println("여자 손님입니다.");
break;
case Person.BABY:
System.out.println("아기 손님입니다.");
break;
}
}
}
2. 열거형의 활용
- Animal, Person도 클래스이다. 다만 키워드 enum을 이용했을 뿐이다.
+ 제네릭(Generic) **
1. 일반화
fcr(10); fct(3.1); fct("abc"); 를
void fct(T a){.........................} //붕어빵 틀
// 결정되지 않은 자료형으로 명명
// 이 틀을 가지고 아래처럼 생성
void fct(int a){.........................} // 붕어빵1
void fct(double a){.........................} // 붕어빵2
void fct(String a){.........................} //붕어빵3
ㄴ 위처럼 특정하지 않은 자료형을 넣었음에도 불구하고 자료형을 임의로 생성하는 것을 제너릭 일반화라고 한다.
※ 특수화(Specialization) : 특수화는 특정 자료형으로 지정하는 것을 특수화라고 한다.
2. 자료형의 안정성을 위한 제네릭
예제_이전)
package ex2;
public class Orange {
int sugarContent; // 당분 함량
public Orange(int sugar) {
sugarContent = sugar;
}
public void showSugarContent() {
System.out.println("당도 " + sugarContent);
}
} // class end
package ex2;
public class FruitBox {
Object item;
public void store(Object item) {
this.item = item;
}
public Object pullOut() { // 뭘 반환할지 모름
return item;
}
} //class end
package ex2;
public class ObjectBaseFruitBox {
public static void main(String[] args) {
FruitBox fBox1 = new FruitBox();
fBox1.store(new Orange(10));
Orange org1 = (Orange) fBox1.pullOut();
org1.showSugarContent();
FruitBox fBox2 = new FruitBox();
fBox2.store("오렌지"); // 말만 오렌지인 문자열
Orange org2 = (Orange) fBox2.pullOut();
org2.showSugarContent();
}
}
출력_이전)
당도 10
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class ex2.Orange (java.lang.String is in module java.base of loader 'bootstrap'; ex2.Orange is in unnamed module of loader 'app')
at ex2.ObjectBaseFruitBox.main(ObjectBaseFruitBox.java:11)
3. 제네릭 클래스 설계
ㄴ T에 해당하는 자료형의 이름은 인스턴스를 생성하는 순간에 결정이 된다.
package ex2;
public class FruitBox<T> { //일반 클래스가 아닌 제네릭 클래스라고 부른다.
// 제네릭은 기본적으로 참조형
T item;
public void store(T item) {
this.item = item;
}
public T pullOut() { // 뭘 반환할지 모름
return item;
}
} //class end
ㄴ 아무거나 담을 수 있었던 과일박스를 제네릭 클래스로 바꾼다.
※ Class ArrayList <E>와 같은 클래스는 제네릭 클래스이다.
4. 제네릭 클래스 기반 인스턴스 생성
5. 제네릭 메서드의 정의와 호출
- 클래스의 메서드만 부분적으로 제네릭화 할 수 있다.
- 제네릭 메서드의 호출 과정에서 전달되는 인자를 통해서 제네릭 자료형을 결정할 수 있으므로 자료형 의 표현은 생략 가능하다.
ㄴ param.showData(); 에서 오브젝트의 클래스가 올 수 있다.
8. 제네릭 메서드와 배열
ㄴ T []가 있으면 배열만 받는다는 의미다 왜? 배열받아야 배열 안에 length가 있는데 T []만 오면 1차원 배열만 오기 때문이다. 배열은 별도이다.
11. 제네릭 클래스의 다양한 상속 방법
12. 제네릭 인터페이스의 구현 방법
+ 컬렉션 프레임워크 ***
1. 컬렉션 프레임워크의 의미와 구조
- 프레임워크 의미 : 잘 정의된, 약속된 구조와 골격
- 자바의 컬렉션 프레임워크 : 인스턴스의 저장과 참조를 위해 잘 정의된, 클래스들의 구조
- 컬렉션 프레임워크가 제공하는 기능의 영역 : 자료구조와 알고리즘
ㄴ 자바의 컬렉션 프레임워크는 별도의 구현과 이해 없이 자료구조와 알고리즘을 적용할 수 있도록 설계된 클래스들의 집합이다. 그러나 자료구조의 이론적인 특성을 안다면, 보다 적절하고 합리적인 활용이 가능하다.
ㄴ 데크, 스택 배열과 같은 자료구조, LinkedList와 같은 참조 형태를 같은 자료구조
ㄴ 알고리즘 : 문제를 해결하는 방법. 쉬운해결방법, 빨리 푸는 해결 방법, 대표적으로 정렬.
- 자바의 프레임워크 중 하나의 컬렉션(모음) 프레임워크
- 인터페이스 골격
- 컬렉션 인터페이스 1대 조상
- 셋 인터페이스 <제네릭>
- 리스트 인터페이스 <제네릭> **
- 큐 인터페이스 <제네릭>
- 맵 개열(컬렉션 개열 아님) **
- 데이터를 저장하는 용도로 사용될 것이다.
2. List <E> <- ArrayList 제네릭 클래스 / 자바 제공
- 해당 인터페이스를 구현하는 대표적인 제네릭 클래스는 ArrayList <E>, LinkedList <E>
- 해당 인터페이스를 구현 클래스의 인스턴스 저장 특징
1) 동일한 인스턴스의 중복 저장을 허용한다.
2) 인스턴스의 저장 순서가 유지된다.
2_1. ArrayList
ArrayList <E> 예시)
package ex3;
import java.util.ArrayList;
public class Ex1_0625 {
public static void main(String[] args) {
// 배열기반으로 데이터 저장
ArrayList<Integer> list = new ArrayList<Integer>();
// 데이터 저장
list.add(new Integer(11));
list.add(new Integer(22));
list.add(new Integer(33));
// 데이터 참조
System.out.println("1차 참조");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 데이터의 삭제
list.remove(0);
System.out.println("2차 참조");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
list.add(11);
list.add(22);
list.add(33);
ㄴ 위와 같이 생략해서 데이터 저장도 가능하다. 오토 박싱 해준다.
ㄴ new ArrayList <Integer>는 메서드는 아니지만 메서드와 같은 역할을 한다.
ㄴ 배열은 데이터를 삭제하면 자료를 정렬해야 했지만 ArrayList는 자동으로 해준다.
결과)
1차 참조
11
22
33
2차 참조
22
33
2_2. linkedList <E>
- 리스트라는 자료구조를 기반으로 데이터를 저장한다.
- ArrayList <E>의 사용 방법과 거의 동일하지만, 데이터를 저장하는 방식에서 큰 차이가 있다.
- 대부분의 경우 AL로 대체할 수 있다.
- 배열에 데이터 정보를 넣는다. 배열의 장점은 구현하기가 쉽다. 입출력이 쉽다. 단점은 배열은 데이터의 저장이 연속 공간이 생겨서 한꺼번에 들어갈 수 있는 메모리 공간이 필요하다. 만약 [0]에 새로운 데이터를 넣는다면 줄줄이 뒤로 밀어야 한다. 삭제, 추가 시에 오버헤드(부담)가 크다. 시간도 많이 걸린다.
- 반면에 ArrayList <E>는 추가, 삭제 시에 오버헤드가 적다. 단점은 구현이 어렵다. 반복문으로 특정 ArrayList를 찾을 시에 순차적으로 찾아야 해서 불필요한 메모리 소모가 있다.
LinkedList <E> 예시)
package ex3;
import java.util.LinkedList;
public class Ex3_LinkedList {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<Integer>();
// 자료 입력
list.add(11); // 추가할때는 add
list.add(22);
list.add(33);
// 자료 출력
System.out.println("1차 출력");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); // 가져올때는 get
}
// 데이터 삭제
list.remove(0); // 첫번째 요소 삭제
System.out.println("2차 출력");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); // 가져올때는 get
}
}
}
ㄴ ArrayList <E>와 동일하다.
3. ArrayList<E>와 LinkedList <E>의 차이점
▶ ArrayList의 특징과 배열의 특징은 일치한다.
- 단점 : 저장소의 용량을 늘리는 과정에서 많은 시간이 소요된다.
- 단점 : 데이터의 삭제에 필요한 연산과정이 매우 길다.
- 장점 : 데이터의 참조가 용이해서 빠른 참조가 가능하다.
▶ LinkedList의 특징과 리스트 자료구조의 특징은 일치한다.
- 장점 : 저장소의 용량을 늘리는 과정이 간단하다.
- 장점 : 데이터의 삭제가 매우 간단하다.
- 단점 : 데이터의 참조가 다소 불편하다.
4. Iterator(아이터 레이터; 반복자)를 이용한 인스턴스의 순차적 접근
- 반복자가 데이터 입력된 순서대로 데이터를 반복적으로 확인하고 데이터가 있으면 출력하게 한다.
Iterator 예시)
package ex3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Ex4_Iterator {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("홍길동"); // 추가할때는 add
list.add("이순신");
list.add("이주성");
list.add("이세종");
Iterator<String> itr = list.iterator();
System.out.println("1차 출력");
while(itr.hasNext()) {
System.out.println(itr.next());
}
}
}
ㄴ Iterator; 반복자
ㄴ hasNext()로 찾고 Next()로 출력한다.
Iterator 삭제 예시)
Iterator<String> itr = list.iterator();
System.out.println("1차 출력");
Iterator<Integer> itr = list.iterator();
System.out.println("1차 출력");
while (itr.hasNext()) {
int curStr = itr.next();
System.out.println(curStr);
if (curStr==30) {
itr.remove();
}
}
System.out.println("삭제 후 출력");
itr = list.iterator(); // 새로운 반복자 생성
while (itr.hasNext())
System.out.println(itr.next());
}
※ List 인터페이스 계열 : ArrayList, LinkedList
1. 입력 순서대로 저장한다.
2. 중복 값도 인정
6. Set <E> <- HashSet <E> 제네릭 클래스 / 자바 제공
※ Set(집합) 인터페이스 계열 : HashSet, TreeSet
1. ex) {1,2,1,3} == {2,3,1}=={1,2,3}는 같다.
2. 입력 순서가 의미 없다.
3. 중복 값 인정 안 한다.
6_1) Set <E> 인터페이스의 특성과 HashSet <E> 클래스
- List <E>를 구현하는 클래스들과 달리 Set <E>를 구현하는 클래스들은 데이터의 저장순서를 유지하지 않는다.
- List<E>를 구현하는 클래스들과 달리 Set <E>를 구현하는 클래스들은 데이터의 중복저장을 허용하지 않는다. 단, 동일 데이터에 대한 기준은 프로그래머가 정의한다.
- 즉, Set<E>를 구현하는 클래스는 '집합"의 성격을 지닌다.
예제)
package ex3;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Ex4_Iterator {
public static void main(String[] args) {
Set<Integer> list = new HashSet<>();
list.add(10); // 추가할때는 add
list.add(20);
list.add(20);
list.add(30);
list.add(40);
Iterator<Integer> itr = list.iterator();
System.out.println("1차 출력");
while (itr.hasNext()) {
int curStr = itr.next();
System.out.println(curStr);
if (curStr==30) {
itr.remove();
}
}
System.out.println("삭제 후 출력");
itr = list.iterator(); // 새로운 반복자 생성
while (itr.hasNext())
System.out.println(itr.next());
}
}
결과)
1차 출력
20
40
10
30
삭제 후 출력
20
40
10
ㄴ 내용 비교하여 데이터 입력하여 중복되는 값을 제외한다.
6_2) 동일 인터페이스의 판단기준
- HashSet <E> 클래스의 인스턴스 동등 비교 방법
- Object 클래스에 정의되어 있는 equals 메서드의 호출 결과와 hashcode 메서드의 호출 결과를 참조하여 인스턴스의 동등 비교를 진행
예제)
package ex3;
import java.util.Iterator;
import java.util.HashSet;
public class Ex5_HashSet_SimpleNumber {
int num;
public Ex5_HashSet_SimpleNumber(int n) {
num = n;
}
@Override
public String toString() {
return String.valueOf(num);
}
public static void main(String[] args) {
HashSet<Ex5_HashSet_SimpleNumber> hSet = new HashSet<Ex5_HashSet_SimpleNumber>();
hSet.add(new Ex5_HashSet_SimpleNumber(10)); // 저장
hSet.add(new Ex5_HashSet_SimpleNumber(20)); // 저장
hSet.add(new Ex5_HashSet_SimpleNumber(20)); // 제외? 인스턴스 비교, 내용 비교 아님
System.out.println("저장된 데이터 수: " + hSet.size());
Iterator<Ex5_HashSet_SimpleNumber> itr = hSet.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
} // class end
6_3) 해시 알고리즘의 이해(데이터의 구분)
- 데이터 < 3, 5, 7, 12, 25, 31 >
- 해시 알고리즘 <num%3>
- 해시 알고리즘은 데이터의 분류에 사용이 된다. 데이터를 3으로 나머지 연산하였을 때 얻게 되는 반환값을 '해시값'으로하여 총 세 개의 부류를 구성하였다.
- 이렇게 분류해 놓으면, 데이터의 검색이 빨라진다. 정수 12가 저장되어 있는지 확인한다고 했을 떄 문제 정수 12의 해시 값으 구한다. 그 다음에 해시 값에 해당하는 부류에서만 정수 12의 존재 유무를 확인하면 된다.
6_4) HashSet<E> 클래스의 동등비교
<검색 1단계> Object 클래스의 hashCode 메소드의 반환 값을 해시 값으로 활용하여 검색의 그룹을 선 택한다.
<검색 2단계> 그룹 내의 인스턴스를 대상으로 Object 클래스의 equals 메소드의 반환 값의 결과로 동 등을 판단한다.
※ hashCode 메소드
- 객체의 해시코드(해시 값)를 반환하는 해시함수(hash function)이다.
- 해시코드는 데이터를 저장하고 검색하는 방법중의 하나인 해싱(hashing)을 구현한 컬렉션 클래스 (HashMap, HashSet 등)에서 객체를 저장하고 읽어올 때 사용하는 키(key)이다.
- equals()를 오버라이딩하면, hashCode()도 적절히 오버라이딩해야 한다.
예시)
package ex3;
import java.util.Iterator;
import java.util.HashSet;
public class Ex5_HashSet_SimpleNumber {
int num;
public Ex5_HashSet_SimpleNumber(int n) {
num = n;
}
@Override
public String toString() {
return String.valueOf(num);
}
@Override
public int hashCode() {
return num%3; // 해시값 : 0,1,2
// 해시값은 상황에 따라서 프로그래머가 설정한다.
}
@Override // 비교할 기준 선택
public boolean equals(Object obj) {
Ex5_HashSet_SimpleNumber cmp = (Ex5_HashSet_SimpleNumber)obj;
if(cmp.num==this.num)
return true;
return false;
}
public static void main(String[] args) {
// System.out.println(new Ex5_HashSet_SimpleNumber(10).hashCode());
// System.out.println(new Ex5_HashSet_SimpleNumber(10).hashCode());
HashSet<Ex5_HashSet_SimpleNumber> hSet = new HashSet<Ex5_HashSet_SimpleNumber>();
hSet.add(new Ex5_HashSet_SimpleNumber(10)); // 저장
hSet.add(new Ex5_HashSet_SimpleNumber(20)); // 저장
hSet.add(new Ex5_HashSet_SimpleNumber(20)); // 제외? 인스턴스 비교, 내용 비교 아님
System.out.println("저장된 데이터 수: " + hSet.size());
Iterator<Ex5_HashSet_SimpleNumber> itr = hSet.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
} // class end
문제3) 아래 Person 클래스의 두 인스턴스를 HashSet<E>에 저장할 때, 두 인스턴스의 데이터(name, age)가 완전히 동일하다면, 하나만 저장하도록 hashCode 메서드와 equals 메서드를 오버라이딩 하시오.
나)
package ex3;
import java.util.HashSet;
import java.util.Iterator;
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + "(" + age + "세)";
}
@Override
public int hashCode() {
return age%3;
}
@Override
public boolean equals(Object obj) {
Person ps = (Person)obj;
if(ps.name==this.name && ps.age==this.age)
return true;
return false;
}
public static void main(String[] args) {
HashSet<Person> hSet = new HashSet<Person>();
hSet.add(new Person("최순이", 10));
hSet.add(new Person("최순이", 20));
hSet.add(new Person("갑돌이", 20));
hSet.add(new Person("갑돌이", 15));
hSet.add(new Person("최순이", 20));
hSet.add(new Person("갑돌이", 20));
System.out.println("데이터 수:" + hSet.size());
Iterator<Person> itr = hSet.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
}
선생님 코딩)
@Override
public int hashCode() {
return name.hashCode()+age%7;
}
@Override
public boolean equals(Object obj) {
Person ps = (Person)obj;
if(ps.name.equals(name) && ps.age==this.age)
return true;
return false;
}
+ Map <K, V> <- HachMap <E> 위와 성격이 다르다 / 데이터 저장 방식이 다르다.
'ICIA 수업일지' 카테고리의 다른 글
2021.06.29 수업일지 (0) | 2021.07.03 |
---|---|
2021.06.28 수업일지 (0) | 2021.07.03 |
2021.06.24 수업일지 (0) | 2021.06.26 |
2021.06.23 수업일지 (0) | 2021.06.26 |
2021.06.22 수업일지 (0) | 2021.06.26 |