1) 예외처리
1-1) finally
1-2) thorws
1-3)throw
1-4) 오버라이딩에서의 예외처리
1-5) 체크예외와 언체크예외 생성
2) API
2-1) java.lang 패키지
2-1.1) Object
2-1.2) String
3) 예외처리와 API를 이용한 예제
2025.02.13 - [AWS활용 자바 부트캠프] - 자바 / 스프링 부트캠프 10일차 ( 람다식 , 내부클래스, 예외처리)
자바 / 스프링 부트캠프 10일차 ( 람다식 , 내부클래스, 예외처리)
어제에 이어서 람다식을 하네요!! 1) 람다식1-1) 추상메서드가 매개변수 , 리턴타입이 없는경우1-2) 추상메서드의 매개변수가있고 리턴타입은 void인경우 1-3) 추상메서드의 매개변수,리턴값 모
ddkk1120.tistory.com
전 글의 예외처리 내용이 이어진다
@@@ 1) 예외처리 @@@
1-1)예외처리(finally)
finally블럭 :
try블럭에서 정상처리 / 예외발생 모두 실행되는블럭
* 중간에 return이 실행되도 반드시 실행되는 영역
package chap10;
/*
* 정상처리 : 12356
* 2/0 오류 : 1456
*
*
* 정상 처리 후 return -> 1235 (6은실행안됨)
* 2/0 오류 return -> 145
*/
public class ExceptionEx3 {
public static void main(String[] args) {
try {
System.out.print(1);
System.out.print(2/0);// /by zero
System.out.print(3);
// return;
} catch (Exception e) {
System.out.print(4);
System.out.print("[메시지 : "+e.getMessage()+"]");
return;
}
finally {
System.out.print(5);
}
System.out.print(6);
}
}
1-2 ) throws
예외를 던진다(나를 호출한 메서드에게)
* throws : 예외처리
* 예외던지기 , 예외선언
* 예외 발생한 메서드에서 발생된 예외를 호출한 메서드로 전달
--> 호출한 메서드에서 예외 발생
package chap10;
public class ExceptionEx4 {
public static void main(String[] args) {
try {
fisrt();
} catch (Exception e) {
System.out.println("main에서 예외 처리");
e.printStackTrace();
}
}
private static void fisrt() throws Exception {
second();
}
private static void second() throws Exception {
System.out.println(Integer.parseInt("abc")); //예외발생
}
}
main에서 예외 처리
java.lang.NumberFormatException: For input string: "abc"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:588)
at java.base/java.lang.Integer.parseInt(Integer.java:685)
at chap10.ExceptionEx4.second(ExceptionEx4.java:19)
at chap10.ExceptionEx4.fisrt(ExceptionEx4.java:15)
at chap10.ExceptionEx4.main(ExceptionEx4.java:7)
second에서 예외처리 시
private static void second() throws Exception {
try {
System.out.println(Integer.parseInt("abc"));
} catch (Exception e) {
System.out.println("second에서 예외처리");
System.out.println("메시지 : "+e.getMessage());
}
}
second에서 예외처리
메시지 : For input string: "abc"
1-3 ) throw
* throw : 예외발생 , 없는 예외를 강제로발생
package chap10;
/*
* throws : 예외처리
*/
public class ExceptionEx5 {
public static void main(String[] args) {
try {
first();
}
catch(Exception e){
System.out.println("main메서드에서 예외 처리");
e.printStackTrace();
}
}
private static void first() {
System.out.println("first 메서드");
second();
}
private static void second() {
System.out.println("second 메서드");
try {
System.out.println(Integer.parseInt("abc"));
} catch (Exception e) {
//e 참조변수 : NUmberFormatException 예외객체 참조
System.out.println("second 메서드에서 예외 처리");
throw e;//다시 예외발생
}
}
}
first 메서드
second 메서드
second 메서드에서 예외 처리
main메서드에서 예외 처리
java.lang.NumberFormatException: For input string: "abc"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:588)
at java.base/java.lang.Integer.parseInt(Integer.java:685)
at chap10.ExceptionEx5.second(ExceptionEx5.java:26)
at chap10.ExceptionEx5.first(ExceptionEx5.java:20)
at chap10.ExceptionEx5.main(ExceptionEx5.java:10)
새로운 예외를 throw로 만들고
catch로 잡아 메시지와
stackTrace 출력
package chap10;
public class ExceptionEx6 {
public static void main(String[] args) {
try {
throw new Exception("예외 강제발생");
} catch (Exception e) {
System.out.println("[ 메시지 : " +e.getMessage()+" ]");
e.printStackTrace();
}
}
}
[ 메시지 : 예외 강제발생 ]
java.lang.Exception: 예외 강제발생
at chap10.ExceptionEx6.main(ExceptionEx6.java:7)
main에서 throws로 예외를 던지면
JVM에서 Exception 예외를 처리함
package chap10;
public class ExceptionEx6 {
public static void main(String[] args) throws Exception {
throw new Exception("예외 강제발생");
}
}
Exception in thread "main" java.lang.Exception: 예외 강제발생
at chap10.ExceptionEx6.main(ExceptionEx6.java:14)
RunTimeException : throws로 던질 필요 없음
(언체크 예외)
package chap10;
public class ExceptionEx6 {
public static void main(String[] args) {
throw new RuntimeException("예외 강제발생");
}
}
1- 4 ) 오버라이딩에서의 예외처리
* 오버라이딩에서의 예외처리 : (같거나 좁은 범위만 가능 )
* 부모클래스의 메서드의 예외처리보다 자손클래스의 메서드의 예외처리는 같거나
* 하위예외클래스로 선언해야함.(RuntimeException의 경우는 허용을 해줄수도있음)
package chap10;
import java.io.IOException;
class Parent{
public void method() throws ClassNotFoundException{
System.out.println("Parent클래스의 method");
}
}
class Child extends Parent{
//자식의 예외는 부모의 예외보다 큰 범위로 설정X
//ex) IOException 예외는 ClassNotFoundException 의 상위이므로 에러발생
public void method() throws IOException{
System.out.println("child클래스의 method()");
}
}
public class ExceptionEx7 {
public static void main(String[] args) {
Child c = new Child();
c.method();
}
}
1-5) 체크예외와 언체크 예외 생성
package chap10;
class LoginFailException extends Exception{
LoginFailException(String msg) {
super(msg);
}
}
class LoginFailException2 extends RuntimeException{
//예외를 잡지않아도되는 언체크 예외를 상속받음
LoginFailException2(String msg) {
super(msg);
}
}
public class ExceptionEx8 {
public static void main(String[] args) {
String id = "hong89"; //id가 hong이 아님
String pw = "1120";
try {
if(!id.equals("hong")|| !pw.equals("1120")) {
//id가 hong과 다르거나 비밀번호가 1120이 아니라면
throw new LoginFailException("아이디나 비번오류");
//예외 생성
}
System.out.println("반갑습니다 hong님(로그인성공)");
} catch (LoginFailException e) {
System.out.println(e.getMessage());
//예외처리
}
//-------------------------------------------------------------------------------
if(!id.equals("hong")|| !pw.equals("1120")) {
//id가 hong과 다르거나 비밀번호가 1120이 아니라면
throw new LoginFailException2("아이디나 비번오류");
//RuntimeException을 상속받았으므로 던지거나 잡지않아도 됨
}
System.out.println("반갑습니다 hong님(로그인성공)");
}
}
아이디나 비번오류(체크)
Exception in thread "main" chap10.LoginFailException2: 아이디나 비번오류(언체크)
at chap10.ExceptionEx8.main(ExceptionEx8.java:43)
내가만든 예외로 푸는 예제
* 화면에서 1~10사이 숫자 입력받아 숫자만큼 * 출력
* 입력값이 숫자아닌경우 InputMismatchException 예외발생
* 예외발생시 숫자만입력하세요 메시지 출력하기 -> 다시 숫자입력받기
* catch scan.next(); 추가하기//하지않는다면 문자가 처리되지않으므로 무한반복
*
* 1~10사이의 숫자가 아닌경우 NumberInputException 클래스의 예외발생하고
* 다시숫자입력받기
package chap10;
import java.util.InputMismatchException;
import java.util.Scanner;
class NumberInputException extends RuntimeException{
NumberInputException(String msg){
super(msg);
}
}
public class Exam3 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(true) {
try {
System.out.print("숫자 입력하세요 : ");
int num = scan.nextInt();
if(10<num || 1>num) {
throw new NumberInputException("1~10만 하세요");
}
for (int i = 0; i < num; i++) {
System.out.print("* ");
}
break;
}
catch (InputMismatchException e) {
System.out.println("숫자만입력하세요 ");
System.out.println("예외명 : "+e.getClass());
scan.next();
}
catch(NumberInputException e ) {
//RuntimeException은 예외를 잡지않아도 되지만
//반복을 위해 잡았음
System.out.println("예외명 : "+e.getClass());
System.out.println(e.getMessage());
}
}
}
}
숫자 입력하세요 : a
숫자만입력하세요
예외명 : class java.util.InputMismatchException
숫자 입력하세요 : 42
예외명 : class chap10.NumberInputException
1~10만 하세요
숫자 입력하세요 : 5
* * * * *
NumberInputException(사용자가 만든 RunTimeException)
를 잡지않는다면 오류구문이 뜨면서break; 됨
숫자 입력하세요 : 12
Exception in thread "main" chap10.NumberInputException: 1~10만 하세요
at chap10.Exam3.main(Exam3.java:32)
Exception을 상속받아 만들었다면
컴파일오류발생
꼭 catch문으로 잡아야함
@@ 2) API @@
2-1) java.lang 패키지(Object , String , Number , System)
2-1.1)Object 클래스
모든 클래스의 최상위클래스
다른 클래스를 상속하지않으면 java.lang.Object 클래스상속
Object 클래스의 메서드
equals( )
* Object 클래스멤버 : equals 메서드
*
* equals : 같은내용인지 판단 리턴용도
* => 내용비교를 위해서 각각의 클래스에서 오버라이딩필요
*
* == : 같은객체판단
package chap11;
import java.util.Objects;
class Equal{
int value;
public Equal(int value) {
this.value = value;
}
//value값이 같으면 True 다르면 false리턴
@Override
public boolean equals(Object obj) {
if(obj instanceof Equal) {
Equal e = (Equal) obj;
return value == e.value;}
else {
return false;
}
}
}
public class EqulasEx1 {
public static void main(String[] args) {
Equal e1 = new Equal(10);
Equal e2 = new Equal(10);
if(e1==e2) {
System.out.println("e1과e2는 같은객체");
}
else {
System.out.println("e1과 e2는 다른객체");
}
System.out.println("e1Hashcode : "+e1.hashCode());
System.out.println("e2Hashcode : "+e2.hashCode());
if(e1.equals(e2)) {
System.out.println("e1과e2는 같은 내용의 객체");
}
else {
System.out.println("e1과 e2는 다른 내용의 객체");
}
}
}
String클래스의 equals
* equlas메서드를 오버라이딩
* 모든객체의 내용비교는 equals 메서드로판단해야함
package chap11;
public class EqualEx2 {
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = "abc";
String str4 = "abc";
//이렇게생성하게되면 문자열풀을 이용함
//자바에서 미리만들어둔 문자열모음 같은거임 (같은곳을 참조하게됨)
if(str1==str2) {
System.out.println("str1과 str2는 같은객체");
}
else {
System.out.println("str1과 str2는 다른객체");
}
if(str1.equals(str2)) {
System.out.println("str1과 str2는 같은 문자열");
}
else {
System.out.println("str1과 str2는 다른 문자열");
}
System.out.println("@@ 문자열풀 이용 @@");
if(str3==str4) {
System.out.println("str3과 str4는 같은객체");
}
else {
System.out.println("str3과 str4는 다른객체");
}
if(str3.equals(str4)) {
System.out.println("str3과 str4는 같은 문자열");
}
else {
System.out.println("str3과 str4는 다른 문자열");
}
}
}
str1과 str2는 다른객체
str1과 str2는 같은 문자열
@@ 문자열풀 이용 @@
str3과 str4는 같은객체
str3과 str4는 같은 문자열
자바가 미리만들어둔 것을 사용한다는 의미임
Hashcode( )
* hashCode 메서드 : JVM이 객체를 구분하기위한 고유값
* 두객체의 해시코드값이 동일한경우는 하나의객체로인식
* 물리적으로 같은객체 - 실제로같은객체
* 논리적으로 같은객체판단 - 내용기준으로 같은 객체인지 판단할 필요성 있음.
*
* 논리적으로 같은객체판단기준
* equals 메서드의 결과가참
* hashCode 메서드값이 같은 경우
*
* 권장사항
* equals 메서드 오버라이딩을 하는 경우 hashCode메서드와 함꼐 오버라이딩 하기
package ex2_Object;
import java.util.Objects;
class HashCode{
int value;
public HashCode(int value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof HashCode) {
HashCode h = (HashCode)obj;
return value == h.value;
}
else {
return false;
}
}
@Override
public int hashCode() {
return value;
}
}
public class HashCodeEx1 {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println("s1 == s2 : "+(s1 == s2));
System.out.println("s1.equals(s2) : "+s1.equals(s2));
//논리적인 hashCode()값
System.out.println("s1.hashCode() : "+s1.hashCode());
System.out.println("s2.hashCode() : "+s2.hashCode());
//물리적인 hashCode()값
System.out.println("System.identityHashCode(h2) : "+System.identityHashCode(s1));
System.out.println("System.identityHashCode(h2) : "+System.identityHashCode(s2));\
HashCode h1 = new HashCode(10);
HashCode h2 = new HashCode(10);
System.out.println("h1 == h2 : "+(h1 == h2));
System.out.println("h1.equals(h2) : "+h1.equals(h2));
System.out.println("h1.hashCode() : "+h1.hashCode());
System.out.println("h2.hashCode() : "+h2.hashCode());
System.out.println("System.identityHashCode(h1) : "+System.identityHashCode(h1));
System.out.println("System.identityHashCode(h2) : "+System.identityHashCode(h2));
}
}
s1 == s2 : false
s1.equals(s2) : true
s1.hashCode() : 96354
s2.hashCode() : 96354
System.identityHashCode(h2) : 424058530
System.identityHashCode(h2) : 321001045
h1 == h2 : false
h1.equals(h2) : true
h1.hashCode() : 10
h2.hashCode() : 10
System.identityHashCode(h1) : 834600351
System.identityHashCode(h2) : 471910020
toString()
* toString() : 객체를 문자열로 바꿔주는 메서드
* Object 구현 : 클래스명@16진수 해쉬코드값 구현(toString 안할 시)
package ex2_Object;
class ToString{
int value;
public ToString(int value) {
super();
this.value = value;
}
@Override
public String toString() {
return "ToString : [value=" + value + "]";
}
}
/-----------------------------------------------------------
class NoToString{
int value;
public NoToString(int value) {
super();
this.value = value;
}
}
//-------------------------------------------------------------------------
public class ToStringEx1 {
public static void main(String[] args) {
ToString t1 = new ToString(10);
System.out.println(t1);
NoToString t2 = new NoToString(10);
System.out.println(t2);
}
}
toString 구현 : ToString : [value=10]
toString 구현X : ex2_Object.NoToString@2f2c9b19
2-1.2) String 클래스
* String 클래스
* 정적인 문자열 , 변경 불가 문자열 객체
* + 연산자가 가능한 유일한클래스
* 대입연산자를 이용해 객채생성이 가능한 유일한 클래스
* final(불변 , 하위 클래스를 둘 수 없는)클래스임
String 주요 메서드
StringBuffer, StringBuilder
String 클래스의 객체는 한번 생성이 되면 수정되지 않는다.
그래서 정적 객체라 말한다
StringBuffer 클래스는 객체 자체의 수정이 가능하다.
StringBuffer 클래스는 동적인 문자열이라고 한다.
String 예시
package ex3_String;
public class StringEx1 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
System.out.println("s1 == s2 : "+(s1==s2));
System.out.println("(s1.equals(s2)) : "+(s1.equals(s2)));
System.out.println(" ");
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println("s3 == s4 : "+(s3==s4));
System.out.println("(s3.equals(s4)) : "+(s3.equals(s4)));
System.out.println("System.identityHashCode(s1) :"+System.identityHashCode(s1));
System.out.println("System.identityHashCode(s2) :"+System.identityHashCode(s2));
System.out.println("System.identityHashCode(s3) :"+System.identityHashCode(s3));
System.out.println("System.identityHashCode(s4) :"+System.identityHashCode(s4));
}
}
s1 == s2 : true
(s1.equals(s2)) : true
s3 == s4 : false
(s3.equals(s4)) : true
System.identityHashCode(s1) :424058530
System.identityHashCode(s2) :424058530
System.identityHashCode(s3) :321001045
System.identityHashCode(s4) :791452441
String 주요메서드 예시
package ex3_String;
public class StringEx2 {
public static void main(String[] args) {
String s = new String("ABCDEFGH");
//s.charAt(4) : s문자열 중 4번인덱스 해당하는 문자 리턴
System.out.println(s.charAt(4));//4번인덱스 문자열 E
//s.compareTo("abc") : s문자열과 "abc" 문자열을 비교해 차이값 정수로리턴
//정렬에 사용됨
//결과값이 양수 : s 문자열이 "abc" 문자열 뒤
//결과값이 음수 : s 문자열이 "abc" 문자열 앞
System.out.println(s.compareTo("abc"));//-32
//IgnoreCase : 대소문자 상관없이
System.out.println(s.compareToIgnoreCase("abcdefgh"));//0
System.out.println();
//마지막문자열이 GH??
System.out.println(s.endsWith("GH"));//true
//시작문자열이 AB??
System.out.println(s.startsWith("AB"));//true
System.out.println();
//내용비교
System.out.println(s.equals("ABCDEFGH"));
System.out.println(s.equalsIgnoreCase("ABcdEfGH"));
s="This is a String";
//s.indexOf('i') : i문자의 인덱스값 리턴
System.out.println(s.indexOf('i'));//2
System.out.println(s.indexOf("is"));//2
//s.lastIndexOf('i') ㅣ i 문자열의 뒤 우선 검색 후 리턴
System.out.println(s.lastIndexOf('i'));//13
//s.indexOf('i',3) : 3번인덱스부터 검색 i문자의 인덱스값 리턴
System.out.println(s.indexOf('i',3));//5
System.out.println();
//s.length() : 문자열의 길이 리턴
System.out.println(s.length());//16
System.out.println();
//문자열 치환
System.out.println(s.replace("is", "QR"));//ThQR QR a String
//정규식 활용한 문자열 치환
System.out.println(s.replaceAll("is", "QR"));
}
}
E
-32
0
true
true
true
true
2
2
13
16
ThQR QR a String
ThQR QR a String
indexOf 활용 예제
indexOf는 찾는 문자가없다면 -1 을 반환함
package ex3_String;
/*
* count(문자열, 찾는문자열 ) 구현하기
* ----> 문자열에서 찾는 문자열의 갯수 리턴
*/
public class Exam1 {
public static void main(String[] args) {
System.out.println(count("12345AB12AB45AB","12"));//2
System.out.println(count("12345AB12AB45AB","AB"));//3
System.out.println(count("12345","AB"));//0
}
private static int count(String s1, String s2) {
int index=0;
int count=0;
int length = s2.length();
while(true) {
index = s1.indexOf(s2,index);
if(index < 0) {
break;
}
count++;
index++;
}return count;
}
}
2
3
0
String은 불변객체
package ex3_String;
class Num{
String value;
Num(String value){
this.value = value;
}
public String toString() {
return value;
}
}
public class StringEx3 {
public static void main(String[] args) {
String str = "ABC123";
System.out.println("main : "+str);
change(str);
System.out.println("change 후 "+str);
System.out.println();
//참조변수임에도 불구하고 값이 안바뀜
// String은 불변객체임 반환해서 새로운 참조값을 얻어내야함
Num num = new Num("3");
System.out.println("mainNum : "+num);
change(num);
System.out.println("change 후 : "+num);
System.out.println();
//일반객체는 메서드안에서도 참조값이 바뀜
String str2 = change2(str);
System.out.println("string반환 후 : "+str2);
}
private static void change(Num n) {
n.value+=456;
System.out.println("change : "+n);
//메서드 내부에서만 생존하는 객체
}
private static void change(String str) {
str+=456;
System.out.println("change : "+str);
//메서드 내부에서만 생존하는 객체
}
private static String change2(String str) {
str+=456;
System.out.println("change2 : "+str);
return str;
}
}
main : ABC123
change : ABC123456
change 후 ABC123
mainNum : 3
change : 3456
change 후 : 3456
change2 : ABC123456
string반환 후 : ABC123456
3)문제풀이
가장어려웠던 문제 2개만 리뷰
예제 1)
1부터 100까지 중 임의의 숫자를 컴퓨터가 저장하고,
값을 입력받아 저장된 값을 맞추는 프로그램을 작성하기
입력 숫자가 1 부터 100까지의 숫자가 아닌 경우 : NumberInputException 예외 발생을 시키고
1 과 100사이의 숫자만 입력하세요 메세지출력
입력 값이 숫자가 아닌경우 : InputMismatchException 예외가 발생
숫자만 입력하세요 메세지 출력
계속 입력을 받는다.
몇번의 입력만에 숫자를 맞추었는지 출력하기.
단 입력 오류된 경우도 입력 건수에 포함된다.
[결과]
1부터 100까지의 숫자를 입력하세요
50
작은수를 입력하세요
1부터 100까지의 숫자를 입력하세요
25
작은수를 입력하세요
1부터 100까지의 숫자를 입력하세요
12
큰수를 입력하세요
1부터 100까지의 숫자를 입력하세요
20
작은수를 입력하세요
1부터 100까지의 숫자를 입력하세요
15
큰수를 입력하세요
1부터 100까지의 숫자를 입력하세요
18
작은수를 입력하세요
1부터 100까지의 숫자를 입력하세요
17
작은수를 입력하세요
1부터 100까지의 숫자를 입력하세요
16
정답입니다. 입력 횟수:8
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
class NumberInputException extends Exception{
NumberInputException(String msg){
super(msg);
}
}//1보다크고100보다 작은수가 입력되지 않았을 때 발생시킬 예외
//---------------------------------------------------------------------------------------------------
public class Test1 {
public static void main(String[] args) {
int randomNum = (int)(Math.random()*100)+1;
Scanner scan = new Scanner(System.in);
int count=0;
while(true) {
try {
System.out.println("1부터100까지의 숫자를 입력하세요");
int num = scan.nextInt();
if(!(1<num && num<100)) {
throw new NumberInputException("1부터100만 입력");//예외발생
}
if(num==randomNum) {
System.out.println("정답입니다 입력횟수 : "+count);
}
else {
if(num<randomNum) {
System.out.println("큰 수를 입력하세요");
}
else {
System.out.println("작은수를 입력하세요");
}
count++;//오답 시 계속 count를 누적
}
} catch (NumberInputException e) {//예외처리
System.out.println("오류메시지 :"+e.getMessage());//오류메시지출력
count++;//count누적
}
catch (InputMismatchException e) {
System.out.println("숫자만 입력하세요");
scan.next();//이걸해야 문자를 처리해서 무한루프가되지않는다
count++;
}
}
}
}
예제4) 난이도 가장높음
* 숫자 맞추기 게임
* 시스템이 4자리의 서로 다른 수를 저장한 후 사용자가 저장된 수를 맞추는 게임
* 자리수도 맞는 경우 : 스트라익
* 자리수는 틀리지만 숫자가 존재하면 : 볼
* 4스트라익이 되면 정답
* NumberInputException을 이용하여 다음의 예외 처리를 할것
* 4자리 수가 아닌 경우는 4자리 숫자를 입력하세요. 를 출력하고 다시 입력을 받기. 입력숫자에는 포함됨
* 중복된 숫자가 입력된 경우 중복된 숫자가 입력되었습니다. 를 출력하고 다시 입력을 받기. 입력숫자에는 포함됨
* InputMismetchException을 이용하여 예외처리
* 만약 숫자 아닌 값이 입력되면 숫자만 가능합니다. 를 출력하고 다시 입력을 받기. 입력숫자에는 포함됨
*
* [결과]
서로다른 4자리 정수를 입력하세요
1234
1234:0스트라이크, 1볼
서로다른 4자리 정수를 입력하세요
5678
5678:2스트라이크, 0볼
서로다른 4자리 정수를 입력하세요
2679
2679정답입니다.
3번 만에 맞추셨습니다. 게임을 종료합니다.
*/
package test;
import java.util.Scanner;
class NumberInputException23 extends Exception{
public NumberInputException23(String msg) {
super(msg);
}
}
class InputMismetchException extends Exception{
public InputMismetchException(String msg) {
super(msg);
}
}
public class Test4 {
public static void main(String[] args) {
int count=0;//시도 횟수 변수
Scanner scan = new Scanner(System.in);
String[] ran = {"0","1","2","3","4","5","6","7","8","9"}; //0부터9까지의 String배열
for (int i = 0; i < 100; i++) {
int a = (int)(Math.random()*ran.length);
int b = (int)(Math.random()*ran.length);
String c = ran[a];
ran[a] = ran[b];
ran[b] = c; //배열의 위치 섞는 알고리즘
}
String rand="";
for (int i = 0; i < 4 ; i++) {
//앞에서부터 4개를 꺼내서 하나의 문자열로만듬
rand+=ran[i];
}
System.out.println(rand);
//재미를 위해서는 이걸 주석처리해야하는데 프로그램동작확인을위해 출력해놈
while(true) {
try {
System.out.println("숫자를 입력하세요 : ");
String next = scan.next();
Integer.parseInt(next);
//int형으로 바꿀수없는 문자가오면 NumberFormatException 발생(catch로잡자)
if(next.length()>4 ||next.length()<4 ) {
throw new NumberInputException23("4자리만");
}
int Ncount=0;
for (int i = next.length()-1; i >=1; i--) {
// 3<->0, 3<->1, 3<->2 , 2<->0 ,2<->1 , 1<->0
//[ 33 22 11 12 00 01 02 03 은 중복 ]
for (int j = 0; j < i; j++) {
if(next.charAt(j) == next.charAt(i)) {
++Ncount;
}
}
}//모든문자열을 뒤져서중복을 찾아내는 알고리즘
if(Ncount >= 1) {
//Ncount가 하나라도 올라갔다면 중복이있단뜻이므로 예외발생
throw new InputMismetchException("숫자중복!!!");
}
//----------------------------------------------------------------------------------
//내가입력한 변수와 시스템이만든 문자 넣기
int[] sbCount = ball(next, rand);//int[] 타입반환하는 메서드
int sCount= sbCount[0];//스트라이크
int bCount= sbCount[1];//볼
if(sCount==4) {
count++;
System.out.println("정답입니다");
System.out.println(count+"시도");
break;
} //4스트라이크 라면 break;
System.out.println(sCount+"스트라이크"+bCount+"볼");
++count;
System.out.println(count+"번쨰 시도중");
//--------------------------------------------------------------------------
} catch (NumberInputException23 e) {
System.out.println(e.getMessage());
++count;
System.out.println(count+"번쨰 시도중");
}
catch(InputMismetchException e) {
System.out.println(e.getMessage());
++count;
System.out.println(count+"번쨰 시도중");
}
catch(NumberFormatException e ) {
System.out.println("숫자만 입력");
++count;
System.out.println(count+"번쨰 시도중");
}
}
}
}
ball 메서드 ( 스트라이크 볼 을 구별해 int형배열에 넣는다)
//스트라이크 볼 판단메서드
private static int[] ball(String next ,String rand) {
int[] sbArr = new int[2];
for (int i = 0; i < next.length(); i++) {
char ch = next.charAt(i);//ch : i번째 문자
int indexOf2 = rand.indexOf(ch);//랜덤 숫자의 ch의 인덱스
//------- rand = 7319 , next = 7421 ------
// 0 번쨰루프 next.charAt(0)==7 rand.indexOf('7') == 0 [0==0] sCount++
// 1 번쨰 루프 next.charAt(1)==4 rand.indexOf('4') == -1(존재하지않는 문자)
// 2 번쨰루프 next.charAt(2)==2 rand.indexOf('2') == -1(존재하지않는 문자)
// 3 번째 루프 next.charAt(3)==1 rand.indexOf('1') == 2 [3!=2] bCount++;
// 1스트라이크 1볼
if(i==indexOf2) {
sbArr[0]++; //strike 1개 증가
}
else if(!(indexOf2<0)) {
sbArr[1]++; //ball 1개 증가
}
}
return sbArr;
}
3260
숫자를 입력하세요 :
a
숫자만 입력
1번쨰 시도중
숫자를 입력하세요 :
321
4자리만
2번쨰 시도중
숫자를 입력하세요 :
3453
숫자중복!!!
3번쨰 시도중
숫자를 입력하세요 :
3214
2스트라이크0볼
4번쨰 시도중
숫자를 입력하세요 :
3260
정답입니다
5시도
처음에 숫자중복을 단일for문으로 해버려서 중복이 됐는데도
예외가발생하지않고 쭉 실행이됐었다
int Ncount=0;
for (int i =1 ; i <next.length(); i++) {
if(next.charAt(0) == next.charAt(i)) {
++Ncount;
}
}
이렇게 했었던것같은데
이렇게되면 00 01 02 03 까지만 비교를 하는셈이다
12 13 23 도 비교해야했는데 ........
예제 5) 나름 어려움 (이건 풀이가 2가지가 존재함)
package test;
/*
* indexOf(문자열,찾는 문자열)
* 문자열에서 찾는 문자열의 위치 값을 출력하는 함수 구현하기
*/
public class Test5 {
public static void main(String[] args) {
indexOf("12345AB12AB45AB", "12"); //12:0,7
indexOf("12345AB12AB45AB", "AB"); //AB:5,9,13
indexOf("12345", "AB"); //AB : 없음
}
}
풀이1
package test;
import java.util.Arrays;
import java.util.Iterator;
/*
* indexOf(문자열,찾는 문자열)
* 문자열에서 찾는 문자열의 위치 값을 출력하는 함수 구현하기
*/
public class Test5 {
public static void main(String[] args) {
indexOf("12345AB12AB45AB", "12"); //12:0,7
indexOf("12345AB12AB45AB", "AB"); //AB:5,9,13
indexOf("12345", "AB"); //AB : 없음
}
private static void indexOf(String string, String string2) {
int count = 0;
int index=0;
String str="";
System.out.print(string2+" : ");
while(true) {
//ex) "12345812".indexOf("12",0);---> 0
///index = 0+1
/// "12345812".indexOf("12",1);---> 6
///index= 6+1
/// "12345812".indexOf("12",7);---> -1 break;
int indexOf = string.indexOf(string2,index);
if(indexOf<0) {
String[] split = str.split(",");
for (int i = 0; i < split.length; i++) {
if(split[i] != split[split.length-1]) {
System.out.print(split[i]+",");
}
else {
System.out.printf(split[i]);
}
}
//split배열은 , 를 기준으로 나눠놨다 배열의마지막만 , 를 찍지않고 출력한다
if(count==0) {
System.out.print("없음");
}
System.out.println();
break;
}
else{
str+=indexOf+",";
//indexof, 문자를 String배열에저장 (마지막,를 안찍으려면 이방법을 써야할것같음)
index =indexOf+1;
//이렇게 해줘야 찾은문자 다음문자부터 구하게됨
count++;
//아예 존재하지않는 문자를 따로처리하기위해 count변수를 이용
}
}
}
}
12 : 0,7
AB : 5,9,13
AB : 없음
풀이2 (더쉽지만 마지막에 , 가 찍히는게 아쉬움)
package test;
import java.util.Arrays;
import java.util.Iterator;
/*
* indexOf(문자열,찾는 문자열)
* 문자열에서 찾는 문자열의 위치 값을 출력하는 함수 구현하기
*/
public class Test5_B {
public static void main(String[] args) {
indexOf("12345AB12AB45AB", "12"); //12:0,7
indexOf("12345AB12AB45AB", "AB"); //AB:5,9,13
indexOf("12345", "AB"); //AB : 없음
}
private static void indexOf(String string, String string2) {
int count = 0;
int index=0;
System.out.print(string2+" : ");
while(true) {
//ex) "12345812".indexOf("12",0);---> 0
///index = 0+1
/// "12345812".indexOf("12",1);---> 6
///index= 6+1
/// "12345812".indexOf("12",7);---> -1 break;
int indexOf = string.indexOf(string2,index);
if(indexOf<0) {
if(count==0) {
System.out.print("없음");
}
System.out.println();
break;
}
else{
System.out.printf(indexOf+",");
index =indexOf+1;//이렇게 해줘야 찾은문자 다음문자부터 구하게됨
count++;//아예 존재하지않는 문자를 따로처리하기위해 count변수를 이용
}
}
}
}
12 : 0,7,
AB : 5,9,13,
AB : 없음
'부트캠프(Java)' 카테고리의 다른 글
자바/스프링 부트캠프 13일차( API {java.util}) (0) | 2025.02.18 |
---|---|
자바/스프링 부트캠프 12일차(API (4) | 2025.02.17 |
자바 / 스프링 부트캠프 10일차 ( 람다식 , 내부클래스, 예외처리) (0) | 2025.02.13 |
자바/스프링 부트캠프 9일차(상속 , 인터페이스 ) (0) | 2025.02.12 |
자바/스프링 개발 부트캠프 8일차(상속) (0) | 2025.02.11 |