[JAVA] Day 16 - Collections [Set ,Queue,Arrays] / < >제너릭 / 예외처리(Exception)

sue·2023년 12월 6일

📒국비학원 [JAVA]

목록 보기
13/20
post-thumbnail

Collections

  • Set : 중복값 받지 x (추가: add)
    Set< > s = new HashSet< >();

HashSet :

① 인터페이스 Set을 구현한 클래스
중복값 허용 x / 순서를 보장하지 않음 (순서가 중요하지 않은 멤버십 확인 / 중복 제거 / 빠른 검색 등에 사용됨)
만 받음

HashMap :

① 인터페이스 Map을 구현한 클래스
순서보장 X - 특정 키에 해당하는 값을 매우 빠르게 검색이 가능
key(유일) - value(중복허용 O) 값을 받음

제너릭 (Generic):

< > 기호를 제너릭이라고 부름 - 해당 클래스나 메서드가 제너릭으로 정의됐다고 함
장점 : 일반적인 는 모든 타입에 대해 동작할 수 있으므로 코드재사용성 가능함
② < String >과 같이 확실한 타입이 들어간다면,해당 타입만 들어가야함
장점: 코드 안전성 보장

예외처리

: 프로그램 실행 중 발생할 수 있는 예외에 대한 처리
try - catch문 (catch 여러번 중복 가능)
② finally를 쓰게되면 해당 블록을 항상 실행해야 함
throw new Exception (" ") : 사용자 에러정의
throws Exception : main메서드 옆에 에러처리

  • Exception이 부모중엔 사장님정도로 낮은 편


🔎 [Eclipse] - [package] - [class] 생성



📌 Note Code


  • Stack : [후입선출] - 뒤로가기 기능 등에 사용 / 가장 최근에 추가된 요소가 가장 먼저 제거되는 원리 (추가 : push / 데이터가 비어있음 : empty / 역순으로 출력: pop)
  • Queue : [선입선출] - 프린트 대기열 등 사용(추가 : offer / add, peek : 요소 제거 + 그 요소 반환, poll : 맨 앞에 있는거 출력 )
  • 배열 -> 확장 for문으로 꺼내면 있는 그대로 유지
  • Arrays.sort (배열을 관리하는 클래스 + 정렬) ->
    가나다라마바사 순서대로 출력


1. Set,Queue, Stack[I]을 사용해서 "서울","부산","대구" 출력하여라

Test1

💻 입력


import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;

public class Test1 {

	public static void main(String[] args) {
		
		//map은 key의 자료형이 set이다
		Set<String> s = new HashSet<String>();
		
	
		s.add("서울");
		s.add("부산");
		s.add("서울");
		
		System.out.println(s); //중복값 x
		
		
		Stack<String> st = new Stack<String>();
		
		st.push("서울");
		st.push("부산");
		st.add("대구");//add = push
		
		System.out.println(st);
		
		while(!st.empty()) { //**기억하기 empty : 비어있다 -> ! 랑 짝꿍 : 비어있지않으면~
			System.out.println(st.pop());//stack - pop : 하나 뽑겠다. / 들어간 순서의 역순으로 출력됨  ,  대구부산서울
		}
		
		
		Queue<String> q = new LinkedList<String>();
				
		q.add("서울");
		q.offer("부산");
		q.offer("대구");
		
		while(q.peek()!=null) {
			System.out.println(q.poll());
		}
		
		String[] str = {"나","다","가","마","아","사","바"};
		
		for(String ss : str) {
			System.out.print(ss+" ");
		}
		System.out.println();
		
		//Arrays : 배열을 관리하는 클래스 - 정렬 Arrays.sort();
		Arrays.sort(str);
		for(String ss : str) {
			System.out.print(ss+" ");
		}
		System.out.println();
	}

}


💡 **출력**
[서울, 부산]
[서울, 부산, 대구]
대구
부산
서울
서울
부산
대구
나 다 가 마 아 사 바 
가 나 다 마 바 사 아 



📌 Note Code


  • ex) b1.get()에서 반환되는 값 = Object 타입
    why? 모든 클래스는 암묵적으로 Object를 상속받음 -> Object의 클래스 멤버 중 get을 사용할 수 있음

  • Box b1 = new Box(); 일반 객체생성일 때,
    str(String 타입) : get(=Object타입) 이니까 [ 大 → 小 ]다운캐스트해서 String타입에 맞춰야 함

  • Box b2 = new Box(); 이렇게 문자열 String만 다룰 수 있게 하는 걸 : 파라미터화
    여기선 String타입만 들어갈 수 있으므로 b2.set(10);이와같이 int가 들어오면 에러남



2. Generic으로 정의 -"서울","부산" 값을 출력하여라

Test2

💻 입력

class Box<T>{ //대문자형태의 자료형 <String / Object / Class Integer...>
	
	private T t;

	public void set(T t) {
		this.t = t;
	}

	public T get() {
		return t;
	}

}

public class Test2 {

	public static void main(String[] args) {

		String str;
		Integer it;
		
		Box b1 = new Box();
		
		b1.set("서울");
		
		str = (String)b1.get();//downcast
		System.out.println(str);
		
		b1.set(10);
		it = (Integer)b1.get();//downcast
		System.out.println(it);
		
		Box<String> b2 = new Box<String>();
		
		b2.set("부산");
		str = b2.get();
		System.out.println(str);
		
		//b2.set(10); String타입만 가능
		
		Box<Integer> b3 = new Box<  Integer>();
		b3.set(30);
		it = b3.get();
		System.out.println(it);
		
		//b3.set("대구"); Integer타입만 가능
		
	}

}


💡 **출력**
서울
10
부산
30



📌 Note Code


  • 절대 오류가 나지 않을 것 같은 사항들은 try-catch문 바깥으로 빼기
  • 예외 날 것 같은 사항 -> try-catch안에 코딩하기
  • catch는 여러번 쓸 수 있음
  • NumberFormatException : 숫자가 아님 / 문자열 형식 -> 숫자로 변환하려고 할때! 주로 Integer.parseInt(), Double.parseDouble() 등의 메소드에서 발생
  • ArithmeticException : 계산식 - 나누기나 나머지 연산에서 분모가 0일때
  • catch문 맨 마지막 - 그냥 Exception 배치
  • e.toString( ) : e.안에 있는 내용을 문자 그대로 보여줌
  • e.printStackTrack( ) : 평소 우리가 보던 빨간 에러들



3. Scanner / 예외처리 - 계산기 만들기

Test3

💻 입력

import java.util.Scanner;

//예외처리
//Exception


public class Test3 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		int num1,num2,result;
		String oper;
		
		try {

			System.out.print("두개의 수?");
			num1 = sc.nextInt();
			num2 = sc.nextInt();
			
			System.out.print("연산자?");
			oper = sc.next();
			
			result = 0; //쓰레기값
			
			if(oper.equals("+"))
				result = num1 + num2;
			else if(oper.equals("-"))
				result = num1 - num2;
			else if(oper.equals("*"))
				result = num1 * num2;
			else if(oper.equals("/"))
				result = num1 / num2;
			
			System.out.printf("%d %s %d = %d",num1,oper,num2,result);
		
		} catch (NumberFormatException e) {
			System.out.println("정수를 입력해!");
		
		} catch (ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다");

		} catch (Exception e) { 
			//Exception 맨 마지막

			System.out.println("넌 그게 숫자로 보여?");
		}

	}
}


💡 **출력**
두개의 수?10 20
연산자?*
10 * 20 = 200

-----------------------------------
두개의 수?10 ?
넌 그게 숫자로 보여?



📌 Note Code


  • throw new Exception ( "하고싶은 말" )
    ① 사용자 정의 에러(throw로 예외를 의도적으로 발생)
    [throws Exception] 예외처리 메서드에 필수로 입력!!

  • void가 없는 static이라도 리턴값 필요함 - 대신 static이라 객체생성 따로 안해도 메모리에 올라가있음

  • 객체생성 대신 clss이름.메서드로 호출하면 됨



4. BufferedReader / 사용자정의에러 - 계산기 만들기

Test4

💻 입력

import java.util.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test4 {

	public static String getOper() throws Exception { //리턴값
		
		BufferedReader br = new BufferedReader(
				new InputStreamReader(System.in));

		String oper = "";

		try {

			System.out.print("연산자?");// +,-,*,/
			oper = br.readLine(); // 아래 catch - **Exception**이 있으므로

			if (!oper.equals("+") && !oper.equals("-") && !oper.equals("*") && !oper.equals("/"))
            
				// 이미 여기서 exception으로 예외처리가 발생했기때문에 아래 catch가 실행안될 수도 있음
                //오버로딩된 생성자로도 볼 수 있음
				throw new Exception("연산자 입력 오류");


            //exception이면 모든걸 exception이 처리하기때문에
			//IOException[입출력 에러] - br.readLine() 에러 막기위해서
		} catch (IOException e) { 
			System.out.println("입력에러!");
		}

		return oper;
	}

	public static void main(String[] args) {
		
		BufferedReader br = new BufferedReader(
				new InputStreamReader(System.in));
		
		int num1,num2,result;
		String oper;
		
		try {
			
			System.out.print("첫번째 수?");
			num1 = Integer.parseInt(br.readLine());

			System.out.print("두번째 수?");
			num2 = Integer.parseInt(br.readLine());

			// 클래스이름.메소드()로 호출
			oper = Test4.getOper(); 

			result = 0; // 쓰레기값

			if(oper.equals("+"))
				result = num1 + num2;
			else if(oper.equals("-"))
				result = num1 - num2;
			else if(oper.equals("*"))
				result = num1 * num2;
			else if(oper.equals("/"))
				result = num1 / num2;
			
			System.out.printf("%d %s %d = %d",num1,oper,num2,result);
	
			
		} catch (Exception e) { //연산자 잘못입력한다면 throw new Exception로 - 에러
			System.out.println(e.toString());
		}
		
	}

}


💡 **출력**
첫번째 수?10
두번째 수?20
연산자??
java.lang.Exception: 연산자 입력 오류



📌 Note Code




5. 에러처리하는 내부공간 따로 만들기 (ex, MyException)

Test5

💻 입력


class MyException extends Exception{// 아주 큰 Exception 안에 내부적으로 저장할 수 있는 저장공간 만듦

	private static final long serialVersionUID = 1L;  //생략가능 - 노란줄싫으면 생성해도 됨
	
	public MyException(String msg) {
   //msg가 super(msg);를 찾음 그리고
   //부모의 오버로딩된 생성자 찾아감 -> Exception으로 받아서 처리하고 e로 결과 내뱉음 
	}
	
}


public class Test5 {

	
	private int value; //instance 초기값 = 0이
	
	//setter
	public void setValue (int value) throws Exception{

		if (value < 0) {
			throw new MyException("0보다 작으면 안돼.");// 사용자 정의 에러
		} else {
			this.value = value;
		}

	}

	//getter
	public int getValue() { 
		return value;
	}

	public static void main(String[] args) {

		Test5 ob = new Test5(); // 위에 내가 만든 메서드 - setter getter 써야하니까
		
		try {
			
			ob.setValue(10); 
			
		} catch (Exception e) { //위에 에러가 있으면 여기서 걸림
			System.out.println(e.toString());
		}
		System.out.println(ob.getValue());// ob에 있는 getValue안에서 갖다줘
		
	}

}


💡 **출력**
10



📌 Note Code


  • str = "a1b2c3"이라고 가정했을 때, 조건에 만족하면 콩 누적 - 기억해두기

    			for (int i = 0; i < str.length(); i++) {
    
    				char ch = str.charAt(i);
    
    				if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
    					eng++; 
    				} else if (ch >= '0' && ch <= '9') {
    					num++;
    				}
    			}
          



6. 사용자 입력값 검증하기

Test6

💻 입력


import java.util.Scanner;


class MyAuthenticator{
	
	public void inputFormat(String str) throws Exception {
		
		//검증 조건
		//1. 사용자가 입력한 문자열이 5~10자이내인지?
		//2. 영문자(대소문자 구분없이), 숫자 혼합입력 - ASCII 값
		//ex) ab324 - 문자의 개수만큼 반복 - charAt(i) >= 'a' / 'z' , '0' 과 '9'
		//영문자인지 체크해  / 숫자인지 체크해 / 영문자면 누적++ => 콩비교 

			if(str.length()<5 || str.length()>10) {
				throw new Exception("문자열의 길이는 5~10자 입니다!");
			}	
				
			
			int eng = 0;
			int num = 0;

			// str = "a1b2c3"
			for (int i = 0; i < str.length(); i++) {

				char ch = str.charAt(i);

				if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
					eng++; // 위에 조건을 만족할때 깡통에 콩하나 집어넣기
				} else if (ch >= '0' && ch <= '9') {
					num++;
				}

			}

			if (eng == 0 || num == 0) {
				throw new Exception("영문자, 숫자 혼용만 가능합니다");
			}
		}
	}

	public class Test6 {

		public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		String str;
		
		MyAuthenticator auth = new MyAuthenticator();
		
		try {
			System.out.print("문자열 : ");
			str = sc.next();
			
			auth.inputFormat(str);//검증
			
			System.out.println(str);
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
	}

}


💡 **출력**
문자열 : aabbcc1578
aabbcc1578


0개의 댓글