웹_프론트_백엔드/JAVA프레임윅기반_풀스택

2020.03.20

shine94 2020. 3. 20. 09:03

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