JAVA - 11

월요일좋아·2022년 10월 13일
0

JAVA

목록 보기
11/12
post-thumbnail

10장. 예외처리

예외와 예외 클래스

오류의 종류

  • 에러(Error) : 관리되지 않은 오류
    • 하드에어의 잘못된 동작 또는 고장으로 인한 오류
    • 에러가 발생되면 프로그램 종료
    • 정상 실행 상태로 돌아갈 수 없음
  • 예외 : 관리되고 있는 오류
    • 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인한 오류
    • 예외가 발생되면 프로그램 종료
    • 예외 처리 추가하면 정상 실행 상태로 돌아갈 수 있음

예외의 종류

  • 일반(컴파일 체크) 예외(Exception)
    • 예외 처리 코드 없으면 컴파일 오류 발생
  • 실행 예외(Runtime Exception)
    • 예외 처리 코드는 생략하더라도 컴파일이 되는 예외ㅣ
    • 경험 따라 예외 처리 코드 작성 필요
    • 문법상으로는 오류가 없으나 실행시 에러 발생하는 것.
  • 예) 강제 형변환 - 원본이 부모객체, 부모 -> 자식

예외 클래스

NullPointerException

  • 객체 참조가 없는 상태
    • null 값 갖는 참조변수로 객체 접근 연산자인 도트 . 사용했을때 발생

ArrayIndexOutOfBoundException

  • 배열에서 인덱스 범위 초과하여 사용할 경우 발생

ClassCastException

  • 타입 변환이 되지 않을 경우 발생
  • 정상 코드
  • 예외 발생 코드

chap03-1 -> ExceotionEx.class

public class ExceotionEx {
    public static void main(String[] args) {

//        NullPointerException 발생
        String data = null;
        System.out.println(data.toString());


//        ArrayIndexOutOfBoundsException 발생
        String data1 = args[0];
        String data2 = args[1]; // 인덱스값 없음

        System.out.println("args[0] : " + data1);
        System.out.println("args[1] : " + data2);
        
        
//        NumberFormatException 발생
        String data1 = "100";
        String data2 = "a100";

        int value1 = Integer.parseInt(data1);   // 문자열 -> 정수로
        int value2 = Integer.parseInt(data2);	// 오류 발생부분

        int result = value1 + value2;
        System.out.println(data1 + " + " + data2 + " = " + result);
    }
}

예외 처리 코드(try - catch - finally)

예외 처리 코드

  • 예외 발생시 프로그램 종료 막고, 정상 실행 유지할 수 있도록 처리
    • 일반 예외 : 반드시 작성해야 컴파일 가능
    • 실행 예외 : 컴파일러가 체크해주지 않으며 개발자 경험에 의해 작성
  • try - catch - finally 블록 이용해 예외 처리 코드 작성

TryCatchEx.class

public class TryCatchEx {
    public static void main(String[] args) {

//        NullPointerException 예외처리
        try {   // try 내부 :  에러가 발생할 수 있는 코드
            String data = null;
            System.out.println(data.toString());
        }
        catch (Exception e) {
            System.out.println("null인 빈 데이터에서는 toString() 메서드를 사용할 때 NullPointException 오류가 발생합니다.");
        }
        
//        ArrayIndexOutOfBoundsException 예외처리
        try {
            String data1 = args[0];
            String data2 = args[1];

            System.out.println("args[0] : " + data1);
            System.out.println("args[1] : " + data2);
        }
        catch (Exception e) {
            System.out.println("배열의 최대 index 범위를 넘어서 사용 :  ArrayIndexOutOfBoundsException 오류 발생");
        }

    }
}

예외 종류에 따른 처리 코드

다중 catch

  • 예외 유형별로 예외 처리 코드 다르게 구현
public class TryCatchEx {
    public static void main(String[] args) {

//       ㅡㅡㅡㅡㅡㅡㅡ[ 다중 catch ]ㅡㅡㅡㅡㅡㅡㅡ
        try {
//        NumberFormatException 발생
            String data1 = "100";
            String data2 = "a100";

            int value1 = Integer.parseInt(data1);   // 문자열 -> 정수로
            int value2 = Integer.parseInt(data2);   // 오류 발생부분

            int result = value1 + value2;
            System.out.println(data1 + " + " + data2 + " = " + result);
        }
//        예외처리를 하나로 모두 처리하면 Exception을 사용하면 됨(Exception e)
//        지정한 예외 상황만 처리하고자 하면 해당 예외클래스를 사용해야함.
        catch (NumberFormatException e) {
            System.out.println("정수로 변환할 수 없습니다.");
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace());
            // e.printStackTrace();
        }
//        다중 catch
//        하나의 try 구문에서 여러개의 지정된 예외처리를 하고자 하면 catch를 여러개 사용할 수 있음.
        catch (NullPointerException e) {
            System.out.println("null을 사용하여 진행할 수 없습니다.");
        }
//        Exception 클래스는 모든 예외 클래스의 최상위 클래스이므로 여러개의 catch문을 사용할 경우 가장 마지막에 입력해야 함
        catch (Exception e) {
            System.out.println("알 수 없는 오류가 발생했습니다.");
        }
    }
}

catch 순서 – 상위 클래스가 위에 위치해야


멀티(multi) catch

  • 자바 7부터는 하나의 catch 블록에서 여러 개의 예외 처리 가능
    • 동일하게 처리하고 싶은 예외를 |로 연결

finally

import java.util.Scanner;

public class TryCatchEx {
    public static void main(String[] args) {

//       ㅡㅡㅡㅡㅡㅡㅡ[ finally ]ㅡㅡㅡㅡㅡㅡㅡ
        
//        finally : try ~ catch 구문에서 예외가 발생하던 발생하지 않던, 무조건 실행되어야 하는 소스코드를 입력하는 부분을 finally라고 함
//                  주로 외부 리소스(파일, 네트워크 연결 등) 사용 시 해당 리소스를 해제하기 위한 목적으로 많이 사용함
//                  (외부 리소스에는 가비지 컬렉터;비사용 메모리 자동 해제 작동X)
        Scanner scanner = new Scanner(System.in);

        try{
            System.out.print("문자를 입력해주세요 : ");
            String data = scanner.nextLine();

            if (data.equals("")) {
                data = null;
            }

            System.out.println("입력된 내용 : " + data.toString());
            System.out.println("여기는 정상 실행 완료 후 실행되는 부분입니다.");
        }
        catch (NullPointerException e) {
            System.out.println("여기는 예외 발생 시 실행되는 부분입니다.");
            System.out.println("예외 이유 : " + e.getMessage());
        }
        finally {
            System.out.println("여기는 무조건 실행되는 부분입니다.");
        }

        System.out.println("try ~ catch 가 완료된 후 실행되는 부분입니다.");

    }
}

finally 예제

//        파일 생성을 통해 finally 테스트
        File file = new File("c:\\test.txt");
        String str = "java file write test";

        try {   // 파일 생성
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            writer.write(str);
            writer.close();
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println("파일 쓰기 사용 시 오류가 발생했습니다.");
        }


        System.out.println("파일 쓰기 완료");

        System.out.println("\n----- 파일 읽기 시작 -----\n");

        FileReader fr = null;
        BufferedReader reader = null;
        try {
            fr = new FileReader("c:\\test.txt");    // 파일 객체를 읽어옴
            reader = new BufferedReader(fr);                // 파일 내용을 읽음

            String tmp; // 글자 읽어오는부분이 저장됨

            while ((tmp = reader.readLine()) != null) { // 한줄씩 읽어와서 tmp에 저장하고 , 그 부분이 null과 같지않으면 while문 실행
                System.out.println("파일 내용 >> " + tmp);
            }
        }
        catch (IOException e) {
            System.out.println("파일 사용 시 오류가 발생했습니다.");
            System.out.println(e.getMessage());
        }

        finally {
            try {
                if (reader != null) reader.close();
                if (fr != null) fr.close();
            }
            catch (Exception e) {
            }
        }
        System.out.println("\n파일 읽기 완료\n");

자동 리소스 닫기

try-with-resources

  • 예외 발생 여부와 상관 없음
  • 사용했던 리소스 객체의 close() 메소드 호출해 리소스 닫음
  • 리소스 객체
    • 각종 입출력스트림, 서버소켓, 소켓, 각종 채널
    • java.lang.AutoCloseable 인터페이스 구현하고 있어야 함
      (해당 인터페이스를 이용하면 finally를 사용하지 않고도 자동으로 파일 닫기 부분이 가능해짐)

java.lang.AutoCloseable 인터페이스 예제

FileInputStream.class

public class FileInputStream implements AutoCloseable{
    private String file;

    public FileInputStream(String file) {
        this.file = file;
    }

    public void read() {
        System.out.println(file + "을 읽습니다.");
    }

    @Override
    public void close() throws Exception {
        System.out.println(file + "을 닫습니다.");
    }
}

TryWithResourceEx.class

public class TryWithResourceEx {
    public static void main(String[] args) {

//        try-with-resources
        try (FileInputStream fis = new FileInputStream("file.txt")) {   // 선언과 동시에 객체 생성(try 구문 안에서만 사용되고 끝나면 삭제됨)
            fis.read();
            throw new Exception();  // 예외 강제 발생 ->
                                    // FileInputStream가 AutoCloseable에서 상속받아 오버라이드한 close가 실행이 됨.
                                    // finally를 사용하지 않아도 콘솔창에 file.txt을 닫습니다. 가 뜸.
        }
        catch (Exception e) {
            System.out.println("예외처리 코드가 실행되었습니다.");
        }
    }
}

예외 떠 넘기기

throws

  • 메소드 선언부 끝에 작성(throw, throws 구분!)
  • 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠 넘기는 역할

Calculator.class

public class Calculator {
    public void sum(String a, String b) {
        try {
            int result = 0;
            int num1 = Integer.parseInt(a);
            int num2 = Integer.parseInt(b);
            result = num1 + num2;
            System.out.println("두 수의 합은 : " + result + "입니다.");
        }
        catch (Exception e) {
            System.out.println("sum 함수에서 연산 시 오류가 발생했습니다.");
        }
    }

//    예외 발생 시 해당 메서드를 사용하는 곳으로 예외를 떠넘김
    public void sub(String a, String b) throws Exception {
        int num1 = Integer.parseInt(a); // 오류가 발생할 가능성이 있는 소스 1
        int num2 = Integer.parseInt(b); // 오류가 발생할 가능성이 있는 소스 2
        int result = num1 - num2;
        System.out.println("두 수의 차는 : " + result + "입니다.");
    }
}

ThrowsEx.class

public class ThrowsEx {
    public static void main(String[] args) {
        Calculator cal = new Calculator();

        try {
            cal.sum("10a", "20");
            cal.sub("10a", "20");   // 실제 오류가 발생하는곳 : Calculator 클래스의 sub() 메소드
                                         // sub() 메소드 뒤에 붙은 throws Exception: 오류 발생시 실행부로 가서 오류처리를 하라는 의미.
        }
        catch (Exception e) {
            System.out.println("실행 시 오류가 발생했습니다.");
        }
    }
}

사용자 정의 예외와 예외 발생

사용자 정의 예외 클래스 선언

  • 자바 표준 API에서 제공하지 않는 예외
  • 애플리케이션 서비스와 관련된 예외
    • ex) 잔고 부족 예외, 계좌 이체 실패 예외, 회원 가입 실패 예외 등...
  • 사용자 정의 예외 클래스 선언 방법

(강제) 예외 발생 시키기

  • 코드에서 예외 발생시키는 법
  • 호출된 곳에서 발생한 예외를 처리하도록
    Account, AccountEx, BalanceInsufficientException

예외 정보 얻기

getMessage()

  • 예외 발생시킬 때 생성자 매개값으로 사용한 메시지 리턴
  • 원인 세분화하기 위해 예외 코드 포함(예: 데이터베이스 예외 코드)
  • catch() 절에서 활용

printStackTrace()

  • 예외 발생 코드 추적한 내용을 모두 콘솔에 출력
  • 프로그램 테스트하면서 오류 찾을 때 유용하게 활용

제네릭

제네릭 타입이란

  • 컴파일 단계에서 잘못된 타입이 사용될 수 있는 문제 제거 가능
  • 컬렉션에서 주로 사용함

제네릭 사용의 이점

  • 컴파일 시 미리 타입 체크를 강하게 해서 에러를 사전에 방지함
  • 실행 시 타입 에러가 나는 것 방지
  • 타입변환 제거 가능
  • 추가는 add, 가져올때는 get
  • (String) 으로 강제 형변환을 해서 데이터를 문자열로 바꿔서 빼주는 부분이 필요한데
    제네릭을 사용하면 그럴필요없음. new ArrayList<String>();

컬렉션

  • 요소(객체)를 수집해 저장하는것
  • 배열의 문제점 해결을 위해 사용하기 시작
    • 저장할 수 있는 객체 수가 배열을 생성할 때 결정됨(크기가 고정)
      -> 불특정 다수의 객체를 저장하기에는 문제가 있음
    • 객체 삭제했을때 해당 인덱스가 비게 됨
      -> 낱알 빠진 옥수수 같은 배열
      -> 객체를 저장하려면 어디가 비어있는지 확인해야됨

컬렉션 프레임워크

  • 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 제공되는 컬렉션 라이브러리
  • java.util 패키지에 포함
  • 인터페이스를 통해서 정형화된 방법으로 다양한 컬렉션 클래스 이용

컬렉션 프레임워크의 주요 인터페이스

  • ArrayList, HashMap 두개만 알면 됨.

List 컬렉션 의 특성

  • 특징
    • 인덱스로 관리된다.
    • 중복해서 객체 저장 가능
  • 구현 클래스 : ArrayList

List 컬렉션의 주요 메소드

List 컬렉션

ArrayList

  • 배열의 특징 : 하나의 이름으로 동일한 타입의 데이터를 여러개 저장하는 데이터 타입, 인덱스 존재(0부터 시작)
    -> ArrayList도 동일함 -> 하나의 이름으로 동일한 타입의 데이터를 여러개 저장하는 데이터타입, 인덱스 존재(0부터 시작)
  • 차이점 : 배열은 크기 고정, ArrayList는 크기가 유동적이다.
  • ArrayList 저장용량 - 초기값 : 10(따로 지정 가능)
    저장 용량을 초과한 객체들이 들어오면 자동적으로 늘어남. 고정도 가능(고정쓸거면 배열을 쓰는게 나음)
  • 객체 제거 : 바로 뒤 인덱스부터 마지막 인덱스까지 모두 앞으로 1씩 당겨짐

ArrayListEx

package chap07;
import java.util.ArrayList;
import java.util.List;


public class ArrayListEx {
	public static void main(String[] args) {
//		뒤의 <String> 는 생략가능.
		ArrayList<String> list = new ArrayList<String>(); // <-- ArrayList  선언방법 1
//		List 클래스가 ArrayList의 부모이므로 부모 타입의 변수에 자식 클래스 타입인
//		ArrayList 객체를 대입하여 사용
//		List<String> list2 = new ArrayList<String>(); // <-- ArrayList  선언방법 2
		
		// list.size() : 현재 list의 길이
		System.out.println("ArrayList 생성\nlist의 길이 : " + list.size());
		list.add("HTML5");
		list.add("CSS3");
		list.add("Bootstrap5");
		list.add("JS ES6");
		list.add("React");
		list.add("Java");
		list.add("Servlet/JSP");
		list.add("Spring framework");
		list.add("Spring boot");
		list.add("Database(mySql)");
		list.add("Python");
		
//		일반 배열은 길이가 고정이지만 arrayList는 입력되는 데이터에따라 크기가 변함
		System.out.println("\n데이터 추가 후 arrayList의 길이 확인 : " + list.size());
		
		String str = list.get(5);
		System.out.println("list의 5번 index의 값 : " + str);
		
		System.out.println("리스트의 전체 내용 출력");
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println("리스트" + i + "번 index의 값 : " + list.get(i));
		}
		
		System.out.println("리스트 안 데이터 삭제하기");
		
		list.remove(5);
		list.remove(2);
		list.remove("JAVA");
		
		System.out.println("\nremove 후 list 변수의 크기");
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println("리스트 " + i + "번 index 값의 : " + list.get(i));
		}
	}
}

Vector

초보자는 잘 사용하지 않는 기능
Board.class

public class Board {
    String subject;
    String content;
    String writer;

    public Board(String subject, String content, String writer) {
        this.subject = subject;
        this.content = content;
        this.writer = writer;
    }
}

VectorEx.class

import java.util.List;
import java.util.Vector;

public class VectorEx {
    public static void main(String[] args) {
        List<Board> list = new Vector<Board>();

        list.add(new Board("제목1", "내용1", "글쓴이1"));
        list.add(new Board("제목2", "내용2", "글쓴이2"));
        list.add(new Board("제목3", "내용3", "글쓴이3"));
        list.add(new Board("제목4", "내용4", "글쓴이4"));
        list.add(new Board("제목5", "내용5", "글쓴이5"));

        list.remove(2);
        list.remove(3);

        for (int i = 0; i < list.size(); i++) {
            Board board = list.get(i);
            System.out.println(board.subject + "\t" + board.content + "\t" + board.writer);
        }
    }
}

LinkedList

Link<E> list = new LinkedList<E>();

  • 특징
    • 인접 참조를 링크해서 체인처럼 관리
    • 특정 인덱스에서 객체를 제거하거나 추가하게 되면 바로 앞뒤 링크만 변경
    • 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList보다 좋은 성능

  • LinkedList 예제
import java.util.LinkedList;
import java.util.List;

public class LinkedListEx {
    public static void main(String[] args) {
        List<String> list1 = new LinkedList<>();

        list1.add("0번");
        list1.add("1번");
        list1.add("3번");

        System.out.println("list1의 0번 index : " + list1.get(0));
        System.out.println("list1의 크기 : " + list1.size());

        list1.set(0, "00번");
        System.out.println("list1의 0번 index : " + list1.get(0));

        list1.remove(2);
        list1.remove(1);
        System.out.println("list1의 크기 : " + list1.size());
    }
}

Set 컬렉션

Set 컬렉션의 특징 및 주요 메소드

  • 특징
    • 수학의 집합에 비유
    • 저장 순서가 유지되지 않음
    • 객체 중복 저장 불가
    • 하나의 null만 저장 가능
  • 구현 클래스
    • HashSet, LinkedHashSet, TreeSet

Set 컬렉션의 특징 및 주요 메소드

  • 주요 메소드
  • 전체 객체 대상으로 한 번씩 반복해 가져오는 반복자(Iterator) 제공
    • 인덱스로 객체를 검색해서 가져오는 메소드 없음

HashSet

Set<E> set = new HashSet<E>();

  • 특징

    • 동일 객체 및 동등 객체는 중복 저장하지 않음
    • 동등 객체 판단 방법 : equals(), HashCode() 로 만들어지는 값을 보고 주소값 비교
      equals(), HashCode() 이 같으면 같다고 판단.
  • HashSet 예제
    HashSetEx.class

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetEx {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("JAVA");
        set.add("JDBC");
        set.add("Servlet/JSP");
        set.add("JAVA");    // HashSet 에서는 중복 데이터 입력되면 자동 제거됨
        set.add("Mybatis");

        int size = set.size();
        System.out.println("HashSet에 저장된 수 : " + size); // 5개 add 했지만 중복데이터 JAVA 1개 삭제됨

        Iterator<String> iterator = set.iterator();
        // iterator.hasNext() 사용하면 리소스/배열/set/map 어디에 적용하든 사용방법 동일하다는 장점이 있다.
        while (iterator.hasNext()) {    // hasNext() : 순서 없음 -> 반복문 사용 불가능. iterator 타입으로 만든 후 hasNext()로 하나씩 끄집어내는것.
                                        // 더 이상 출력할 것이 없으면 false.
            String element = iterator.next();
            System.out.println("\t" + element);
        }

        // for (String item : set) <- 이런 형식으로 for문 사용도 가능

        set.remove("JDBC");
        set.remove("Mybatis");

        System.out.println("HashSet에 저장된 수 : " + set.size());

        iterator = set.iterator();

        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println("\t" + element);
        }

        set.clear();
        if (set.isEmpty()) {    // isEmpty 로 내부 데이터 비어있는지 확인
            System.out.println("HashSet이 비어있음.");
        }
    }
}

HashSet 문제 1

문제 1) HashSet 을 사용하여 로또 번호 7개를 생성하는 프로그램을 작성하세요.

public class HashSetEx2 {
    public static void main(String[] args) {
//        문제 1) HashSet 을 사용하여 로또 번호 7개를 생성하는 프로그램을 작성하세요.
        Set<Integer> lotto = new HashSet<>();
        int count = 0;

        while (count < 7) {
            int rnd = (int)(Math.random() * 45) + 1;

            if (lotto.add(rnd)) {
                count++;

                if (lotto.size() == 7) {
                    break;
                }
            }
        }

        int rnd = (int)(Math.random() * 45) + 1;

        Iterator<Integer> iter = lotto.iterator();
        String number = "";
        while (iter.hasNext()) {
            int num = iter.next();
            number += String.valueOf(num) + " ";
        }
        System.out.println(number);

        System.out.println("\n\n");

Member.class

public class Member {
    public String name;
    public int age;

    public Member(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

HashSetEx2

public class HashSetEx2 {
    public static void main(String[] args) {

//       예제 
        Set<Member> set = new HashSet<>();

        set.add(new Member("홍길동", 30));
        set.add(new Member("홍길동", 30));

//        아래 코드 실행 결과 : 2.
//        중복인데 2개 인 이유 ? new 키워드를 쓰면 객체 생성 -> 주소값이 다름. 같아보이지만 주소값 다르면 다른 데이터로 인식
        System.out.println("총 객체 수 : " + set.size());
//        Member 클래스에서 equals(), hashCode() 오버라이드 추가 하면 결과값 1로 변함.
//        Why?
//        동일 객체임을 판단하는 기준이 equals(), hashCode() 이기 때문.

    }
}

💎Map 컬렉션

Map 컬렉션의 특징 및 주요 메소드

  • 특징
    • 키(key)와 값(value)으로 구성된 Map.Entry 객체를 저장하는 구조
    • 키와 값은 모두 객체
    • 키는 중복될 수 없지만 값은 중복 저장 가능
  • 구현 클래스
    • HashMap, Hashtable, LinkedHashMap, Properties, TreeMap
      이 중, 주로 쓰는것은 HashMap이다.
  • 주요 메소드
    네모박스 체크한 4가지만 알면 됨.

HashMap

  • 특징
    웬만하면 키 타입은 String을 많이 사용함.
    • 키 객체는 hashCode()와 equals() 를 재정의해 동등 객체가 될 조건을 정해야
  • HashMap 예제
    HashMapEx.class
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapEx {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();

        System.out.println("HashMap 의 크기 : " + map.size()); // 결과 : 0

        map.put("아이유", 30);
        map.put("유인나", 32);
        map.put("유재석", 50);
        map.put("홍길동", 30);
        map.put("이순신", 40);

        System.out.println("HashMap 의 크기 : " + map.size()); // 결과 : 5
        
//        찾기
//        map.get(키) : 해당 키가 가지고 있는 값 출력
        System.out.println("\t홍길동 : " + map.get("홍길동"));
        System.out.println();

        Set<String> keySet = map.keySet();
        Iterator<String> keyIter = keySet.iterator();   // 키를 모두 가져와서 iterator에 집어넣기

        while (keyIter.hasNext()) {
            String key = keyIter.next();    // 해당 key에 깃발 꽂기
            int value = map.get(key);   // get(key)로 키값에 맞는 값 가져오기
            System.out.println("key : " + key + " \tvalue : " + value);
        }
        System.out.println();
        
//        삭제
        if (map.containsKey("김종국")) {   // 김종국이라는 키가 있으면
            map.remove("김종국");     // 유재석이라는 키 삭제, 없으면 삭제 안함
        }

//        삭제
        map.remove("이순신");
        map.remove("홍길동");
        System.out.println("HashMap의 크기 : " + map.size());

        map.clear();
        System.out.println("HashMap의 크기 : " + map.size());
       
    }
}

HashTable

  • 특징
    • 키 객체 만드는 법은 HashMap과 동일
    • Hashtable은 스레드 동기화(synchronization)가 된 상태
    • 복수의 스레드가 동시에 Hashtable에 접근해서 객체를 추가, 삭제하더라도 스레드에 안전(thread safe)
  • HashTable 예제
    HashTable.class
import java.util.Hashtable;
import java.util.Map;
import java.util.Scanner;

public class HashTableEx {
    public static void main(String[] args) {
        Map<String, String> map = new Hashtable<>();

        map.put("spring", "12");
        map.put("summer", "123");
        map.put("fall", "1234");
        map.put("winter", "12345");

        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("아이디와 비밀번호를 입력해주세요.");
            System.out.print("아이디 : ");
            String id = scanner.nextLine();

            System.out.print("비밀번호 : ");
            String password = scanner.nextLine();
            System.out.println();

            if (map.containsKey(id)) {  // containsKey : id 받은것에서 key를 찾는것
                if (map.get(id).equals(password)) {
                    System.out.println("로그인 되었습니다.");
                    break;
                }
                else {
                    System.out.println("비밀번호가 일치하지 않습니다.");
                }
            }
            else {
                System.out.println("입력하신 아이디가 존재하지 않습니다.");
            }
        }
    }
}

Properties

  • 특징
    • 키와 값을 String 타입으로 제한한 Map 컬렉션
    • Properties는 프로퍼티(~.properties) 파일을 읽어 들일 때 주로 사용(스프링 사용시 필요)
    • HashTable과 같음. Key, 값이 String으로 제한되어있다는 차이점만 있을 뿐.
  • 프로퍼티(~.properties) 파일
    • 옵션 정보, 데이터베이스 연결 정보, 국제화(다국어) 정보를 기록
      • 텍스트 파일로 활용
    • 애플리케이션에서 주로 변경이 잦은 문자열을 저장
      • 유지 보수를 편리하게 만들어 줌
  • 키와 값이 = 기호로 연결되어 있는 텍스트 파일

    • ISO 8859-1 문자셋으로 저장
    • 한글은 유니코드(Unicode)로 변환되어 저장
  • 프로퍼티 예제
    파일 생성 -> database.properties

driver=oracle.jdbc.OracleDriver
url=jdk:oracle:thin:@localhost:1521:orcl
username=scott
password=tiger

PropertiesEx.class

import java.io.FileReader;
import java.net.URLDecoder;
import java.util.Properties;

public class PropertiesEx {
    public static void main(String[] args) throws Exception {   // throws Exception 추가(파일 불러오는 것이기때문)
        Properties properties = new Properties();

//        Properties는 String 타입으로 고정되어있기때문에 <String> 생략
//        현재 클래스의 리스소를 가져온다(src폴더의 리소스) -> getResource(위치) : 파일의 위치 , getPath() : 파일 위치의 전체 경로 가져오기
        String path = PropertiesEx.class.getResource("database.properties").getPath();  // 불러올 파일 위치 잡기

        path = URLDecoder.decode(path, "utf-8");    // 한글이 있을때 안깨지게 utf-8 로 바꿔라
        System.out.println("파일 경로 : " + path); // 결과값 : /D:/java505/intellij/chap07/out/production/chap07/database.properties

//        load를 통해 파일 내용을 읽어옴
        properties.load(new FileReader(path));  // 해당 파일 가져오기,


        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

        System.out.println("driver : " + driver);
        System.out.println("url : " + url);
        System.out.println("username : " + username);
        System.out.println("password : " + password);

    }
}

0개의 댓글