1. 메소드 정의(definition)
수식어(modifier) 리턴타입 메소드이름 매개변수 리스트(parameter list) {
메소드 본체(body)
}
2. 메소드 호출(call, invoke), 메소드 리턴(return)
[실습코드]
1. 과제, 369게임 만들기
package practice.game369;
/*
* 369게임
* 1~100 까지의 자연수를 나열하되,
* 10개 단위로 줄바꿈을 하고
* 숫자에 3,6,9 중 하나라도 있으면 * 표시를 하기
*
* 주의! 순환문, 조건문만 사용(문자열 관련하여 사용 금지)
*
* 패키지: practice.game369
* 클래스: Game369
*/
public class Game369 {
public static void main(String[] args) {
System.out.println("369 게임/n/n");
int result1 = 0;
int result2 = 0;
for(int i = 1; i <= 100; i++) {
//나머지 연산을 이용하여 끝에 3,6,9만 남기기
result1 = i % 10;
//몫 연산을 이용하여 십의 자리 3,6,9들을 * 하기 위해
result2 = i / 10;
//1~100 까지의 자연수를 나열하되,
//숫자에 3,6,9 중 하나라도 있으면 * 표시하기
if(result1 % 3 == 0 && result1 != 0) {
System.out.print("*\t");
} else if(result2 % 3 == 0 && result2 != 0) {
System.out.print("*\t");
} else {
System.out.print(i + "\t");
}
// 10개 단위로 줄바꿈
if(i % 10 == 0) {
System.out.println();
}
}
}
}
2. Lec12_Method
1) com.lec.java.method01패키지, Method01Main 클래스
package com.lec.java.method01;
/* 메소드 (Method):
반복되는 코드, 내용, 재사용해야할 코드들을 한 뭉치로 묶어서
따로 메소드로 만들은 다음(정의) 이를 필요할때마다 사용(호출)한다.
※ 자바는 '함수(function)' 가 따로 없습니다
그러나 교육하면서 편의상, 혼용하여 말하겠습니다.
메소드 정의:
메소드는 main 메소드 바깥에서!!, class 안에서 정의!!
메소드 정의구문:
수식어 리턴타입 메소드이름(매개변수, ...) { ... }
modifier return_type method_name(parameter, ...) { ... }
수식어(modifier) : public, static, private, ... (생략 가능)
매개변수 (parameter) : 메소드 호출시 넘겨주는 값.
리턴타입 (return type) : 메소드 종료후 호출한 쪽에 돌려주는 값
void, int, double, String ...
(리턴타입 void의 의미는 되돌려주는 값(return 값)이 없다는 의미)
메소드 signature 란?:
메소드 이름 + 매개변수 리스트 (매개변수 타입, 순서, 개수)
sayAge(int)
sayHello3(String, int)
*/
public class Method01Main {
public static void main(String[] args) {
System.out.println("메소드(함수) Method(Function)");
System.out.println("안녕하세요.");
System.out.println("제 이름은 윤종섭 입니다.");
System.out.println("안녕하세요.");
System.out.println("제 이름은 이강혁입니다.");
// 위의 코드들을 보다시피 이름 빼고 반복되어 있음.
// 이름만 바꾸고 노다가 식으로 계속 코딩하는건 말이 안됨 ㅜ^ㅜ oh no~~
// 이런 경우 메소드를 사용하여 간편하게 코딩 가능함!!
System.out.println();
System.out.println("메소드 사용(호출)");
System.out.println("메소드를 사용하는 것을 호출하는 것이라고 함~");
// 메소드 호출구문
// 메소드 이름(매개변수 값(들)...)
// 메소드 호출 : method call, method invoke
sayHello("장수영");
sayHello("고유성");
System.out.println();
sayAge(16);
sayAge(20);
com.lec.java.method01.Method01Main.sayAge(21);
System.out.println();
sayHello2("김우경", 25);
// 정의되어 있는 매개변수 리스트와 다르게 호출하려 하면
//sayHello2(100, 200); // 오류
// The method sayHello2(String, int) int the type
// Method01Main is not applicable for the arguments(int,int)
System.out.println();
sayHello3("방석민", 26);
System.out.println("\n프로그램 종료");
} // end main()
// 메소드 정의는 메소드 바깥에서!!, class 안에서 정의!!
// 왜? 메인 메소드 안에 메소드, 즉 메소드 안에 메소드를 선언하는꼴
// 자바는 메소드 안에 메소드 호출 불가능!
// 메소드 이름 : sayHello
// 매개변수 : name (매개변수가 필요 없는 경우는 생략 가능)
// 메소드 위에 아래와 같이 javadoc 타입 주석을 달 수 있다.
/**
* 메소드이름 : sayHello
* 주어진 이름을 출력합니다.
* @param name 이름
*/
public static void sayHello(String name) {
System.out.println("안녕하세요");
System.out.println("제 이름은 " + name + "입니다.");
} // end sayHello()
// 메소드 이름 : sayAge
// 매개변수 : int 타입의 age
// 리턴타입 : void(리턴값이 없다)
public static void sayAge(int age) {
System.out.println("Hi~");
System.out.println("제 나이는 " + age + "입니다.");
} // end sayAge()
// 메소드 이름 : sayHello2
// 매개변수
// 1) String name
// 2) int age
// 리턴타입 : void
public static void sayHello2(String name, int age) {
System.out.println("안녕!");
System.out.println("내 이름은 " + name + "입니다.");
System.out.println("내 나이는 " + age + "살입니다.");
} // end sayHello2()
public static void sayHello3(String name, int age) {
sayHello(name);
sayAge(age);
} // end sayHello3()
} // end class
/*
* 이클립스 단축키 : 메소드 이름위에서
* F3 : Open Declaration (이 메소드 는 어디서 정의?)
* CTRL + ALT + H : Open Call Hierarchy (이 메소드는 어디서 호출되나?)
*
* 디버깅 :
* step into : 현재 디버깅 위치의 메소드 호출 내부 코드 진입
* step out (step return) : 현재 디버깅 진행중인 메소드 return 까지 진행후 호출한 측으로 돌아감
* resume : 다음 breakpoint 까지 쭈욱 진행
*/
[추가] javadoc 주석을 통해 메소드 명에 커서를 가져다놓으면 내가 설정한 해당 설명을 볼 수 있음
[추가] 메소드를 만들면 아래와 그림과 같이 확인할 수 있음
[추가] 메서드 관련하여 어떻게 작동되는지 디버그 모드로 확인하기
> breakpoint 설정
> 디버그 모드!! > " Q. 메서드 호출하면 어디로 갈까??? "
> step into(현재 디버깅 위치의 메소드 호출 내부 코드 진입)을 이용 > " 호출한 해당 메서드의 바디로 들어감! "
> 메서드 작업이 모두 끝나면 다시 메인 메서드로 돌아감
2) com.lec.java.method02패키지, Method02Main 클래스
package com.lec.java.method02;
/* return 의 믜미
*
* 1. 메소드를 호출한 곳으로 값을 한 개 리턴할 수 있다.
* 2. 메소드 종료
* 3. 메소드 정의시 명시한 리턴타입의 값이 '반드시' 리턴되어야 한다
* (혹은 리턴타입으로 형변환 가능한 값이)
*/
public class Method02Main {
public static void main(String[] args) {
System.out.println("메소드의 리턴 타입");
int sum = add(110, 220);
System.out.println("sum = " + sum);
sum = add(10, 20) + add(30, 40);
System.out.println("sum = " + sum);
sum = add(50, add(10, 20));
System.out.println("sum = " + sum);
System.out.println("sum = " + (add(10, -40) + add(add(20, 30) + 10, 10)));
System.out.println();
System.out.println("sub = " + sub(100, 10));
System.out.println("multiply = " + multiply(100, 10));
System.out.println("divide = " + divide(100, 10));
System.out.println("divide2 = " + divide2(100, 10));
System.out.println("divide2 = " + divide2(100, 0));
System.out.println("\n프로그램 종료");
} // end main()
// 메소드 이름: add
// 매개변수:
// 1) int x
// 2) int y
// 리턴타입: int
public static int add(int x, int y) {
int result = x + y;
return result; // 리턴! (메소드 종료, 값을 리턴)
} // end add()
// 메소드 이름: sub
// 매개변수:
// 1) int x
// 2) int y
// 리턴타입: int
public static int sub(int x, int y) {
int result = x - y;
return result;
} // end sub()
// 메소드 이름: multiply
// 매개변수:
// 1) int x
// 2) int y
// 리턴타입: int
public static int multiply(int x, int y) {
int result = x * y;
return result; // 리턴! (메소드 종료, 값을 리턴)
} // end multiply()
// public static int multiply(int x, int y) {
// return x * y;
//
// } // end multiply()
// 메소드 이름: divide
// 매개변수:
// 1) int x
// 2) int y
// 기능: x를 y로 나눈 몫을 리턴하는 메소드
// 리턴타입: int
public static int divide(int x, int y) {
int result = x / y;
return result; // 리턴! (메소드 종료, 값을 리턴)
} // end divide()
// public static int divide(int x, int y) {
// return x / y;
// } // end divide()
// 메소드 이름: divide2
// 매개변수:
// 1) int x
// 2) int y
// 만약에 y 가 0 이면 --> "0으로 나눌수 없습니다"
// y 가 0 이 아니면 --> "몫은 ~~이고 , 나머지는 ~~ 입니다"
// 리턴타입: String ★
public static String divide2(int x, int y) {
String result = "";
int mok = 0;
int rest = 0;
if(y == 0) {
result = "0으로 나눌 수 없습니다.";
} else {
mok = x / y;
rest = x % y;
result = "몫은 " + mok + ", 나머지는" + rest + "입니다.";
}
return result; // 리턴! (메소드 종료, 값을 리턴)
} // end divide2()
// public static String divide2(int x, int y) {
// String result;
// if (y == 0) {
// result = "0으로 나눌 수 없어요!!!";
// } else {
// result = "나눈 몫은 " + (x / y) + "\n"
// + "나눈 나머지는 " + (x % y) + "입니다.";
// } // end else
//
// return result;
// } // end divide2();
} // end class
[추가] 리턴값을 int로 설정
> 리터값 설정하고 막상 리턴값이 없으면 This method must return a result of type int 오류 발생
3) com.lec.java.method03 패키지, Method03Main 클래스
package com.lec.java.method03;
import java.util.Scanner;
/* 메소드 연습
* 국어, 영어, 수학 점수를 입력 받아서
* 총점, 평균, 학점을 출력하는 프로그램
*
* 총점, 평균, 학점을 구하는 각각의 메소드들을 작성하여 프로그램 완성하기
*
* [입력예]
* 78 98 57
*
* [출력예]
* 총점: 233
* 평균: 77.66666666666667
* 학점: C
*/
public class Method03Main {
public static void main(String[] args) {
System.out.println("메소드 연습");
// 국어, 영어, 수학 점수를 위한 int 변수를 선언
int korean, english, math;
// 키보드를 통해서 점수를 입력 받고 저장
Scanner sc = new Scanner(System.in);
System.out.println("국어 점수:");
korean = sc.nextInt();
System.out.println("영어 점수:");
english = sc.nextInt();
System.out.println("수학 점수:");
math = sc.nextInt();
sc.close();
// 입력된 점수 확인
System.out.println();
System.out.println("===================");
System.out.println("국어: " + korean);
System.out.println("영어: " + english);
System.out.println("수학: " + math);
System.out.println("===================");
// calcTotal() 메소드를 정의+호출 하여 총점 계산하고 출력
// public static int calcTotal(int kor, int eng, int math)
int total = calcTotal(korean, english, math);
System.out.println("총점: " + total);
// calcAvg() 메소드를 정의+호출 하여 평균 계산하고 출력
// public static double calcAvg(int total)
double avg = calcAvg(total);
System.out.println("평균: " + avg);
// calcGrade() 메소드를 정의+호출 하여 학점(A, B, C, D, F)을 출력
// 평균 90 이상이면 A, 80 이상이면 B, 70 이상이면 C, 60 이상이면 D
// 나머지는 F
// public static char calcGrade(double avg)
char grade = calcGrade(avg);
System.out.println("학점: " + grade);
System.out.println("\n프로그램 종료");
} // end main()
// calcTotal
// 기능: 국어, 영어, 수학 점수를 입력 받아서 총점을 리턴하는 메소드
// return: int
// method name: calcTotal
// arguments:
// 1) int kor: 국어 점수
// 2) int eng: 영어 점수
// 3) int math: 수학 점수
public static int calcTotal(int kor, int eng, int math) {
return kor + eng + math;
} // end calcTotal()
// calcAvg
// 기능: 총점을 입력받아서 평균을 리턴하는 메소드
// return: double
// method name: calcAvg
// arguments: int total - 총점
public static double calcAvg(int total) {
return (double)total / 3;
} // end calcAvg
// calcGrade
// 기능: 평균을 받아서 등급을 리턴하는 메소드
// 평균 90 이상이면 'A', 80 이상이면 'B', 70 이상이면 'C', 60 이상이면 'D'
// 나머지는 'F' 리턴
// return: char
// method name: calcGrade
// arguments: double avg - 평균
public static char calcGrade(double avg) {
// char grade;
// if (avg >= 90) {
// grade = 'A';
// } else if (avg >= 80) {
// grade = 'B';
// } else if (avg >= 70) {
// grade = 'C';
// } else if (avg >= 60) {
// grade = 'D';
// } else {
// grade = 'F';
// }
// return grade;
// 아래 코드가 깔끔.
if(avg >= 90) {return 'A';}
if(avg >= 80) {return 'B';}
if(avg >= 70) {return 'C';}
if(avg >= 60) {return 'D';}
return 'F';
} // end calcGrade
} // end class
4) com.lec.java.method04 패키지, Method04Main 클래스
package com.lec.java.method04;
import java.util.Scanner;
/*
*
* public static double inputNumber(Scanner sc)
*
* Scanner 객체를 매개변수로 받을수 있다.
* (메소드 안에서 Scanner 객체를 생성할수는 있으나... 제대로 close() 되지 않은채 생성하면 문제 발생)
*
* 이클립스에서 함수 호출 위에서 F3 누르면 정의 로 넘어감
*/
public class Method04Main {
public static void main(String[] args) {
System.out.println("메소드 연습");
Scanner sc = new Scanner(System.in);
double num1 = inputNumber(sc);
sc.close();
System.out.println("num1 = " + num1);
System.out.println("\n프로그램 종료");
} // end main()
// method name: inputNumber
// return: double
// arguments: Scanner sc - 키보드 입력을 위한 객체
// 기능: 키보드로 입력받은 double형 데이터를 리턴
// 0 ~ 100까지 이외의 범위는 다시 입력 받는 기능 추가
public static double inputNumber(Scanner sc) {
double result = 0.0;
while(true) {
System.out.print("숫자 입력(0 ~ 100) : ");
result = sc.nextDouble();
if(0 < 0.0 || 100.0 < result) {
System.out.print("다시 입력해주세요 : ");
continue;
}
break;
}
return result;
}
} // end class
5) com.lec.java.method06 Method06Main
package com.lec.java.method06;
/* Method Overloading (메소드 중복 정의)
같은 이름으로 메소드를 매개변수 리스트를 달리하여 중복 정의,
즉, 이름이 같아도 메소드 signature 가 다르면 중복정의 가능.
Method Signature 란
메소드 이름 + 매개변수 리스트 (parameter list)
1. 매개변수의 개수가 다르거나
2. 매개변수의 자료형이 다르거나
3. 매개변수의 순서가 다를 때
위 3개를 '매개변수 리스트' 라 한다
메소드의 리턴 타입만 다른 경우는 중복 정의할 수 없다!!
메소드 오버로딩의 장점:
동일한 동작을 하는 메소드에 대해 매개변수만 달리하여 중복정의 하면
이 메소드를 사용하는 입장에선 여러타입의 이름을 익힐 필요가 없다.
*/
public class Method06Main {
public static void main(String[] args) {
System.out.println("Method Overloading (메소드 중복 정의)");
sayHello();
sayHello("남윤주");
sayHello(20);
sayHello("이승환", 23);
sayHello(27, "이승환");
//sayHello(100, 100); // 오류
// The method sayHello(int, String) in the type Method06Main
// is not applicable for the arguments (int, int)
byte b = 10;
sayHello(b); // byte 타입이 int 타입으로 자동형변환되어 메서드 실행됨
// 3-2 메서드를 만드는 순간 3-2 메서드 실행
// 왜냐하면 자동형변환 순서(byte -> short -> int)에 의해서...!!
// 메소드 오버로딩의 장점
System.out.println(10);
System.out.println(3.14);
System.out.println("Hello");
System.out.println(new int[4]);
// 메소드 오버로딩이 없다면....!
// 타입별로 메서드를 만들어야 하고 각기 다른 이름을 다외워야함
// 생각만해도 힘들다 ㅜ^ㅜ
System.out.println("\n프로그램 종료");
} // end main()
// 1
public static void sayHello() {
System.out.println("sayHello() 호출");
System.out.println("안녕하세요!");
}
// 2
public static void sayHello(String name) {
System.out.println("sayHello(String) 호출");
System.out.println("Hi~");
System.out.println("제 이름은 " + name + "입니다.");
}
// 오류!!!
// 리턴타입이 다르다고 해서 오버로딩이 되지 않는다.
// 왜냐하면 시그니쳐로 구분하고
// 이미 void sayHello() 메소드가 있기 때문에 불가능
// public static int sayHello() {
//
// }
// 3-1
public static void sayHello(int age) {
System.out.println("sayHello(int) 호출");
System.out.println("My age is" + age);
}
// 3-2
public static void sayHello(short age) {
System.out.println("sayHello(short) 호출");
System.out.println("My age is" + age);
}
// 4
public static void sayHello(String name, int age) {
System.out.println("sayHello(String, int) 호출");
System.out.println("헬로~");
System.out.println("이름 : " + name + ", 나이 : " + age);
}
// 5
// 4번 메서드랑 5번 메서드는 다른 메서드(이름만 같은 다른 메서드, 오버로딩)
// 시그니처 즉, 매개변수의 순서가 다르기 때문이다
public static void sayHello(int age, String name) {
System.out.println("sayHello(int, String) 호출");
System.out.println("헬로~");
System.out.println("이름 : " + name + ", 나이 : " + age);
}
} // end class
[추가] Method Signature
[추가] Duplicate method sayHello() in type Method06Main, 중복 선언 불가하다고 오류남!
오버로딩이 중복 선언이 가능하다고 하는데 어떻게 할 수 있을까??
> 매개변수가 다르면 같은 이름이더라도 선언 가능
> 리턴 타입이 다르다고 해서 오버로딩 되지 않는다.
왜냐하면 시그니쳐로 구분하고 리턴타입은 다르지만 이미 void sayHello() 메소드가 있기 때문에 불가능
[추가] byte 타입이 int 타입으로 자동형변환되어 public static void sayHello(int age) 메서드가 실행됨
> 3-2 메서드를 만들면...!!
> public static void sayHello(short age)가 메서드가 실행됨
왜냐하면 자동형변환 순서(byte -> short -> int)에 의해서...!!
6) com.lec.java.method07 Method07Main
package com.lec.java.method07;
import java.util.Random;
public class Method07Main {
public static void main(String[] args) {
System.out.println("Math 객체");
// Math.random() : 0.0 <= r < 1.0 사이의 난수 발생(double)
double r;
for (int i = 0; i < 10; i++) {
r = Math.random();
System.out.println(r);
}
System.out.println();
// double Math.floor(num): num을 넘지 않는 가장 큰 정수(바닥)
// double Math.ceil(num): num보다 큰 가장 작은 정수(천장)
// long Math.round(num): num에서 소수점 사사오입 (반올림)
System.out.println(Math.floor(2.7)); // 출력값 : 2.0
System.out.println(Math.ceil(2.7)); // 출력값 : 3.0
System.out.println(Math.round(2.7)); // 출력값 : 3
System.out.println(Math.floor(-1.2)); // 출력값 : -2.0
System.out.println(Math.ceil(-1.2)); // 출력값 : -1.0
System.out.println(Math.round(-1.2)); // 출력값 : -1
System.out.println(Math.floor(-2.8)); // 출력값 : -3.0
System.out.println(Math.ceil(-2.8)); // 출력값 : -2.0
System.out.println(Math.round(-2.8)); // 출력값 : -3
System.out.println();
System.out.println("1,2,3 범위중 난수 발생시키기");
for (int i = 0; i < 5; i++) {
double num;
num = Math.random(); // 0.0 <= num < 1.0
num = num * 3; // 0.0 <= num < 3.0
num += 1; // 1.0 <= num <= 3.0
System.out.println((int)num);
}
System.out.println();
System.out.println("로또: 1 ~ 45 숫자중에서 랜덤으로 6개 출력");
for (int i = 0; i < 6; i++) {
double num;
num = Math.random();
num = num * 45;
num += 1;
System.out.print((int)num + " ");
}
System.out.println();
System.out.println();
System.out.println("한줄로 쓰기!!");
for (int i = 0; i < 6; i++) {
System.out.print((int)(Math.random() * 45 + 1) + " ");
}
System.out.println();
System.out.println();
System.out.println("Random 객체 사용하여 난수 출력");
Random rand = new Random();
// 0, 1, 2 사이 난수 5개 발생
for (int i = 0; i < 5; i++) {
System.out.print(rand.nextInt(3) + ", ");
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
7) com.lec.java.method08 패키지, Method08Main 클래스
package com.lec.java.method08;
import java.util.Random;
import java.util.Scanner;
/* 메소드 연습 : 컴퓨터 생각 맞추기 게임
* 1. 메뉴를 보여주고
* 2. 사용자로부터의 입력을 받고
* 3. 컴퓨터의 생각(난수)와 비교 판정 내기
* 4. 사용자가 메뉴에서 '종료' 누르면 종료 시키기
*/
public class Method08Main {
public static void main(String[] args) {
System.out.println("컴퓨터 생각 맞추기 게임");
Scanner sc = new Scanner(System.in);
while(true) {
showMenu();
int userChoice = inputChoice(sc);
if(userChoice == 0) {break;}
int com = new Random().nextInt(3) + 1;
if(com == userChoice) {
System.out.println("맞췄습니다!");
} else {
System.out.println("틀렸습니다. 컴퓨터 생각은 = " + com);
}
}
sc.close();
System.out.println("\n프로그램 종료");
} // end main
// 메뉴 보여주기
// 메소드 이름 : showMenu()
public static void showMenu() {
System.out.println("-------------------------");
System.out.println("COM의 생각을 맞춰보세요!");
System.out.println("1]");
System.out.println("2]");
System.out.println("3]");
System.out.println("0] 종료");
System.out.println("-------------------------");
System.out.print("선택 : ");
}
// 메소드 이름 : inputChoice
// 매개변수 : Scanner sc
// 리턴타입 : int
// 0 ~ 3 까지의 정수를 Scanner 로부터 입력받아 리턴
// 범위 밖의 수일때는 재입력받는다
public static int inputChoice(Scanner sc) {
int choice;
while(true) {
choice = sc.nextInt();
if(0 <= choice && choice <= 3) {return choice;}
System.out.println("다시 입력해주세요.");
}
}
} // end class
8) com.lec.java.method10 패키지, Method10Main 클래스
package com.lec.java.method10;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
/* 메소드와 배열
* 매개변수가 배열, 리턴타입이 배열
*/
// 메소드는 가급적으로 주로 동사로 많이 만든다(개발자들의 암묵적인 약속)
// 자바는 camelCase을 많이 사용함!!
// 파이썬, C언어은 주로 snake_case를 많이 사용함
public class Method10Main {
public static void main(String[] args) {
System.out.println("메소드와 배열");
Scanner sc = new Scanner(System.in);
int[] score = new int[10]; // 10명의 점수
// 점수를 입력받아서 score 배열에 저장
inputScore(sc, score);
// 저장된 점수 확인
displayScore(score);
// 총 점 계산
int total = calcTotal(score);
System.out.println("총점 : " + total);
sc.close();
System.out.println("랜덤 숫자 배열 생성");
double[] randArr = genRandom(10);
System.out.println(Arrays.toString(randArr));
System.out.println("\n프로그램 종료");
} // end main()
// method name: inputScore
// return: void
// arguments:
// 1) Scanner sc - 입력장치
// 2) int[] score: 점수를 입력받아서 저장할 배열
public static void inputScore(Scanner sc, int[] score) {
for (int i = 0; i < score.length; i++) {
System.out.println("점수 : " + (i) + " 입력 : ");
score[i] = sc.nextInt();
}
}
// method name: displayScore
// return: void
// arguments: int[] score - 출력할 점수가 저장된 배열
public static void displayScore(int[] score) {
System.out.println("점수 출력");
System.out.println("---------------------------------");
for(int x : score) {
System.out.println(x + ", ");
}
System.out.println();
System.out.println("---------------------------------");
}
// method name: calcTotal
// return: int (계산된 총점을 리턴)
// arguments: int[] score (점수들을 저장한 배열)
public static int calcTotal(int[] score) {
int total = 0;
for(int x : score) {
total += x;
}
return total;
}
// method name: genRandom()
// return: double[] (생성된 난수 배열)
// arguments: n 생성할 난수 개수
public static double[] genRandom(int n) {
double[] arr = new double[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = Math.random();
}
return arr;
}
} // end class Method09Main
9) com.lec.java.method11 패키지, Method11Main 클래스
package com.lec.java.method11;
/* 재귀 호출 (recursive call)
* 메소드(혹은 함수) 내부에서 메소드가 자기 자신을 또다시 호출하는 것.
*
* 장점:
* 복잡한 문제를 간단하고 논리적으로 기술 가능.
*
* 단점 & 주의 :
* 메모리 부담 발생
* 무한히 재귀호출 할수 없다. --> Stack Overflow 발생
* 따라서 재귀호출이 종료되는 조건이 반드시 필요하다.
*
*/
public class Method11Main {
public static void main(String[] args) {
System.out.println("재귀 호출 (recursive call)");
System.out.println("재귀 메소드(recursive method)");
// Stack 메모리 용량 초과 : StackOverflowError
//showNumber(1); //오류
// Exception in thread "main" java.lang.StackOverflowError
// Heap 메모리 용량 초과 : OutOfMemoryError
//int n = Integer.MAX_VALUE;
//double[] arr = new double[n]; // 오류
// Exception in thread "main" java.lang.OutOfMemoryError
for(int n = 0; n < 10; n++) {
System.out.println(n + "! = " + calcFactorial(n));
}
System.out.println("\n프로그램 종료");
} // end main()
// 무한정 재귀호출 불가
public static void showNumber(int n) {
System.out.println(n);
showNumber(n + 1);
}
// method name: calcFactorial
// return: long (num의 팩토리얼을 계산해서 리턴)
// arguments: long num
// 기능:
// if n == 0, 0! = 1
// if n > 0, n! = n * (n - 1)!
// if n < 0, 계산 불가
public static long calcFactorial(long num) {
long result = 0L;
if(num == 0) { // 0!, 재귀호출 종료 조건
result = 1L;
} else if (num > 0) {
result = num * calcFactorial(num - 1); // 재귀 호출!
} else {
System.out.println("음수 팩토리얼은 계산 불가");
}
return result;
}
} // end class
10) com.lec.java.method09 패키지, Method09Main 클래스
package com.lec.java.method09;
/* Call By Value : 값에 의한 호출
Call By Reference : 참조에 의한 호출
메소드 호출시 매개변수에 넘겨주는 값의 '복사' 가 발생.
자바에선
primitive type 이 매개변수 인 경우 Call By Value
: '값' 이 복사된다
: 메소드에서 매개변수 값을 변경해도 호출한 원본 쪽은 변화 없슴
reference type 이 매개변수 인 경우 Call By Reference 발생
: '주소' 가 복사된다.
: 메소드에서 매개변수 를 통해 변경하면 호출한 원본 쪽도 변화 발생
*/
public class Method09Main {
public static void main(String[] args) {
System.out.println("Call By Value : 값에 의한 호출");
System.out.println("Call By Reference : 참조에 의한 호출");
int n = 10;
incNum(n);
System.out.println("incNum(int) 호출 후 n의 값 : " + n);
System.out.println();
int[] arr = {10};
incNum(arr);
System.out.println("incNum(int[]) 호출 후 arr[0]의 값 : " + arr[0]);
System.out.println("\n프로그램 종료");
} // end main()
public static void incNum(int value) {
value++;
System.out.println("incNum(int) : " + value);
}
public static void incNum(int[] arr) {
arr[0]++;
System.out.println("inNum(int[]) : " + arr[0]);
}
} // end class
3. Lec19_String
1) com.lec.java.string01 패키지, String01Main 클래스
package com.lec.java.string01;
import java.util.Arrays;
import java.util.Scanner;
/* 문자열 (String) 관련 메소드들
*
* https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
* - 문자열 메소드는 꼭 정독해보세요.
* - 매개변수의 의미, 동작의 의미, 리턴값의 의미 꼭 숙지해주세요
* - 인스턴스 메소드 인지, 클래스 메소드(static) 인지 구분
*/
public class String01Main {
public static void main(String[] args) {
System.out.println("String 클래스의 메소드들");
String str1 = "AbCdEfg";
String str2 = "안녕하세요~";
System.out.println();
System.out.println("length()"); // 문자의 개수
System.out.println("str1 길이 : " + str1.length());
System.out.println("str2 길이 : " + str2.length());
System.out.println();
System.out.println("concat()"); // 문자열 연결 (concatenation)
System.out.println(str1.concat(str2));
System.out.println(str2.concat(str1));
System.out.println(str1.concat(str2).length());
String str3 = str1.concat(str2);
System.out.println(str3.length());
// ★주의★
// 문자열(String) 은 변경불가(immutable) 이기 때문에
// 메소드 수행했다고 하여 원본이 변경되지 않는다.
System.out.println();
str1.concat(str2);
System.out.println(str1); // 변경 안됨
str1 = str1.concat(str2); // 변경하려면 이와 같이 덮어쓰기 해야 한다.
System.out.println(str1);
// ★주의★
// empty 문자열과 null 은 다르다
// null 인 경우 메소드 수행하면 NullPointerException 발생!
str3 = ""; // empty 문자열, String객체는 존재하나 비어있는 문자열
System.out.println(str3.length());
str3 = null; // null, String객체가 존재하지 않음
//System.out.println(str3.length()); // 오류
// java.lang.NullPointerException
System.out.println();
System.out.println("charAt(index)"); // 문자열 안의 특정위치(index)의 문자 리턴
// 인덱스 범위 벗어나면 StringIndexOutOfBoundsException
// 문자열 인덱스는 0 부터 시작!
System.out.println(str1.charAt(0));
System.out.println(str1.charAt(1));
// 인덱스 범위 벗어나게 출력 시도..!
//System.out.println(str1.charAt(20)); // 오류
// java.lang.StringIndexOutOfBoundsException
System.out.println();
// 문자열 안에서 특정 문자(char) 혹은 문자열(String)의 위치(index), 발견 못하면 -1 리턴
System.out.println("indexOf(char), indexOf(String)");
System.out.println(str1.indexOf('c'));
System.out.println(str2.indexOf('요'));
System.out.println(str2.indexOf("하세"));
System.out.println();
System.out.println("toUpperCase(), toLowerCase"); // 대문자 변환, 소문자 변환
System.out.println(str1.toUpperCase());
System.out.println(str1.toLowerCase());
System.out.println();
System.out.println("startWith(prefix)"); // 문자열이 주어진 prefix문자열로 시작하는지 여부
// true/false 리턴
String prefix = "http://";
String url = "www.google.com";
System.out.println(url.startsWith(prefix));
if(!url.startsWith(prefix)) {
String newUr = prefix.concat(url);
}
System.out.println();
System.out.println("split(regex)"); // 문자열을 주어진 문자열로 쪼개어 String[] 리턴
String str4 = "HH:MM:SS";
String[] strings = str4.split(":");
System.out.println(Arrays.toString(strings));
// 공백기준으로 쪼갤때는 정규표현식의 \\s+ 사용하기 : 공백, 탭, 줄바꿈
str4 = "Hello My World";
strings = str4.split("\\s+");
System.out.println(Arrays.toString(strings));
str4 = " Hello\tMy\nWorld";
strings = str4.split("\\s+");
System.out.println(Arrays.toString(strings));
// 단! "|" 을 할경우는 주의, ※ split(정규표현식) 을 사용하는 메소드임
String str5 = "HH|MM|SS";
strings = str5.split("\\|");
for(String x : strings) {
System.out.println(x);
}
// 년,월,일,시,분,초 분리하기
str4 = "2018-08-16 14:34:52";
String data = str4.split("\\s+")[0];
String time = str4.split("\\s+")[1];
System.out.println("data = " + data);
System.out.println("time = " + time);
String year = data.split("-")[0];
System.out.println("year = " + year);
// String.join()
// 문자열들, 문자열 배열 --> 하나의 문자열로 합하기 split() 과 반대
System.out.println();
System.out.println("String.join(delimeter, elements ...)");
String[] str7 = {"Alice", "Bob", "Carol"};
System.out.println(String.join(" - ", str7));
System.out.println();
// 문자열의 일부분 추출 beginIndex ~ endIndex직전까지, 인덱스 범위 벗어마면 IndexOutOfBoundsException
System.out.println("substring(beginIndex, endIndex)");
String str8 = "Hello Java";
System.out.println(str8.substring(2, 5)); // 2부터 5 전까지
System.out.println(str8.substring(6)); // 6부터 끝까지
System.out.println();
System.out.println("trim()"); // 좌우의 여백 제거
String str9 = " 김동후 ";
System.out.println("[" + str9 + "]");
System.out.println("[" + str9.trim() + "]");
System.out.println();
System.out.println("replace(target, replacement)"); // 문자열 치환 target → replacement
String str10 = "Hello Language My Language";
System.out.println(str10.replace("My", "Our"));
System.out.println(str10.replace("Language", "Java"));
System.out.println();
// 정규표현식 사용버젼, replaceAll() 매칭되는것 전부 치환, replaceFirst() 첫매칭만 치환
System.out.println("replaceAll(regex, replacement), replaceFirst(regex, replacement)");
System.out.println(str10.replaceAll("Language", "자바"));
System.out.println(str10.replaceFirst("Language", "자바"));
System.out.println("\n프로그램 종료");
} // end main()
} // end class
① str1.length() : 문자의 개수
② str1.concat(str2) : 문자열 연결(concatenation)
③ charAt(index) : 문자열 안의 특정위치(index)의 문자 리턴,
④ indexOf(String) : 문자열 안에서 특정 문자(char) 혹은 문자열(String)의 위치(index), 발견 못하면 -1 리턴
⑤ str1.toUpperCase() : 대문자 변환
⑥ str1.toLowerCase() : 소문자 변환
⑦ str1.startWith(prefix) : 문자열이 주어진 prefix문자열로 시작하는지 여부 true/false 리턴
⑧ str1.split(regex) : 문자열을 주어진 문자열로 쪼개어 String[] 리턴
⑨ String.join(str1, str2, ... ) : 문자열들, 문자열 배열 --> 하나의 문자열로 합하기
⑩ str1.substring(beginIndex, endIndex) : 문자열의 일부분 추출 beginIndex ~ endIndex직전까지
⑪ str1.trim() : 좌우의 여백 제거
⑫ str1.replace(target, replacement) : target → replacement
⑬ str1.replaceAll(regex, replacement) : replaceAll() 매칭되는것 전부 치환
⑭ str1.replaceFirst(regex, replacement) : replaceFirst() 첫매칭만 치환
⑮ str1.equals(str2) : 문자열 비교(대소문자 가림)
⑯ str1.equalsIgnoreCase(str2) : 문자열 비교(대소문자 안가림)
⑰ String.format("String format", strarguments) : 문자열 형식 지정
⑱ Arrays.toString(array) : 배열 내용 출력
2) com.lec.java.string04 패키지, String04Main 클래스
package com.lec.java.string04;
import java.util.StringTokenizer;
/* StringTokenizer 클래스
token ? : '규칙'에 의해 구분된 더 이상 나눌수 없는 문자요소(문자열)
(문법적으로 더 이상 나눌 수 없는 기본적인 언어요소)
*/
public class String04Main {
public static void main(String[] args) {
System.out.println("StringTokenizer 클래스");
// token <- '규칙'에 의해 구분된 문자덩어리(문자열)?
String str1 = "13:46:12";
StringTokenizer tokenizer = new StringTokenizer(str1, ":");
System.out.println("토큰 개수 : " + tokenizer.countTokens());
while(tokenizer.hasMoreElements()) {
System.out.println(tokenizer.nextToken());
}
//tokenizer.nextElement(); // 오류
// java.util.NoSuchElementException
System.out.println();
String str2 = "abc:def:ghi:jkl:mno"; // : 로 토큰분리
StringTokenizer token2 = new StringTokenizer(str2, ":");
System.out.println("토큰 개수 : " + token2.countTokens());
while(tokenizer.hasMoreElements()) {
System.out.println(tokenizer.nextToken());
} // end while()
System.out.println();
String str3 = "2015/04/08"; // / 로 토큰분리
StringTokenizer token3 = new StringTokenizer(str3, "/");
while(tokenizer.hasMoreElements()) {
System.out.println(tokenizer.nextToken());
} // end while()
System.out.println();
String str4 = "2015년-4월-8일"; // - 으로 토큰분리
StringTokenizer token4 = new StringTokenizer(str4, "-");
while (token4.hasMoreTokens()) {
System.out.println(token4.nextToken());
} // end while
System.out.println();
String str5 = "2015-04-08 14:10:55";
StringTokenizer token5 = new StringTokenizer(str5, "-: ");
while(token5.hasMoreTokens()) {
System.out.println(token5.nextToken());
}
System.out.println();
// StringTokenizer 생성자의 세번째 매개변수를 true 로 주면
// delimiter 도 token 으로 추출된다
String str6 = "num += 1";
StringTokenizer token6 = new StringTokenizer(str6, "+=", true);
while(token6.hasMoreTokens()) {
System.out.println(token6.nextToken());
}
// 실습]
// 다음과 같은 수식이 있을때 토큰들을 분리해네세요
// 연산자 + - / * 괄호 ( )
// 10 + (name * 2) / num8- (+3)
// 힌트]
// 일단 공백으로 분리 split()
// 그리고 나서 각각을 StringTokenizer 함
// 결과
// 10, +, (, name, *, 2, ), /, num8, -, (, +, 3, ),
System.out.println();
System.out.println("수식 분석기");
String expr = "10 + (name * 2) / num8 - (+3)";
for(String s : expr.split("\\s+")) {
StringTokenizer exprTokenizer = new StringTokenizer(s, "+-*/()", true);
while(exprTokenizer.hasMoreTokens()) {
System.out.print(exprTokenizer.nextToken() + ", ");
}
}
System.out.println();
System.out.println("\n프로그램 종료");
} // end main()
} // end class
3) practice.capitalize 패키지, LetterCapitalize 클래스
package practice.capitalize;
import java.util.Scanner;
import java.util.StringTokenizer;
/* LetterCapitalize
* 문장을 입력하고, 단어의 앞 문자를 대문자로 만들어 출력하기를 반복하다가
* quit 을 입력 받으면 종료하기
*
* [입력예]
* hello my world
* [출력예]
* Hello My World
*/
public class LetterCapitalize {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String line;
String[] words;
while(true) {
line = sc.nextLine();
if(line.trim().equalsIgnoreCase("quit")) {break;}
line = line.toLowerCase(); // 일단 소문자로 변환
words = line.split("\\s+"); // 공백 기준 단어 쪼개기
for(String word : words) {
if(word.length() > 0) {
// 앞글자 떼어내기
String firstLetter = word.substring(0, 1).toUpperCase();
String rest = word.substring(1); // 나머지 문자열
System.out.print(firstLetter + rest + " "); // 최종 출력
}
}
System.out.println();
}
sc.close();
} // end main()
} // end class
4) practice.isogram 패키지, Isogram 클래스
package practice.isogram;
import java.util.Arrays;
import java.util.Scanner;
/* Isogram
문자열을 입력받으면 isogram 여부를 판단하여 true/false 를 출력하다가, quit 가 입력되면 종료
isogram 이란? : 중복된 알파벳이 없는 단어
isogram 예) Machine, isogram, Alphabet, quit
*/
public class Isogram {
// substring()과 indexOF(), charAt() 사용
static boolean is_isogram2(String str) {
str = str.toLowerCase();
for(int i = 0; i < str.length() - 1; i++) {
if(str.substring(i + 1).indexOf(str.charAt(i)) != -1) return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String word;
while(true) {
word = sc.next();
if(word.equalsIgnoreCase("quit")) break;
System.out.println(is_isogram2(word));
}
sc.close();
} // end main()
} // end class
'웹_프론트_백엔드 > JAVA프레임윅기반_풀스택' 카테고리의 다른 글
2020.03.24 (0) | 2020.03.24 |
---|---|
2020.03.23 (0) | 2020.03.23 |
2020.03.19 (0) | 2020.03.19 |
2020.03.18 (0) | 2020.03.18 |
2020.03.17 (0) | 2020.03.17 |