Java #8

황현근·2023년 5월 9일
0

Acorn-Academy

목록 보기
18/28
post-thumbnail

HashMap & HashSet

HashMap은 Map 인터페이스의 구현체로, HashTable과 유사한 자료구조로 데이터를 저장한다.

HashSet은 Set 인터페이스의 구현체로, 내부적으로 HashMap을 사용하기 때문에 HashTable과 유사한 자료구조로 데이터를 저장한다.

1. 데이터 저장 형태

  • HashMap은 Key-Value 쌍 형태로 데이터를 저장하며, Key와 Value의 mapping을 유지하고 있다.
  • HashSet은 객체 그 자체를 저장한다.
  • 위에서 HashMap을 내부적으로 사용한다고 했는데, Key 값으로는 삽입되는 객체 그 자체를, Value 값으로는 HashSet 내부 구현 코드에서 미리 선언해둔 dummy 객체를 사용한다.

  1. 중복 허용 여부
  • HashMap은 (중복 Key 값을 허용하지 않기 때문에) 단 하나의 NULL 값을 Key 값으로 가질 수 있고, 여러 NULL 값을 Value 값으로 가질 수 있다.
 {'a': 1, 'b': 1, 'c': 2}
  • HashSet단 하나의 NULL 값을 가질 수 있다.
{'a', 'b', 'c'}


3. NULL 허용 여부

  • HashMap은 (중복 Key 값을 허용하지 않기 때문에) 단 하나의 NULL 값을 Key 값으로 가질 수 있고, 여러 NULL 값을 Value 값으로 가질 수 있다.
  • HashSet은 단 하나의 NULL 값을 가질 수 있다.

  1. 데이터 삽입 방법
  • HashMapput() 메서드를 사용하여 데이터를 삽입하는데, Key-Value 쌍 데이터의 형태를 저장하기 때문에 삽입 연산 동안 단 하나의 객체가 생성된다.
  • HashSetadd() 메서드를 사용하여 데이터를 삽입하는데, 객체 그 자체를 저장하고 내부적으로 HashMap을 사용하기 때문에 삽입되는 객체(Key값)dummy 객체(Value 값), 총 두 개의 객체가 삽입 연산 동안 생성된다.

  1. 성능
  • HashMap이 HashSet보다 빠르다. 데이터의 유일함(Uniqueness)을 유지하기 위해 항상 HashMap이 HashSet보다 선호된다.

Collections

collections는 재사용이 가능한 collection 자료구조를 구현하는 클래스 및 인터페이스의 집합이다.

  • collection은 객체이며, 배열처럼 여러 원소를 담을 수 있는 자료구조다.

Java의 colleciton 자료구조 유형

자바에서는 크게 네 가지 collection 자료구조 유형이 있다.

  • 순서가 있는 목록List형.

  • 순서가 중요하지 않은 목록Set형.

  • 먼저 들어온 것이 먼저 나가는(FIFO) Queue형.

  • Key-Value 형태로 저장되는 Map형.

  • 배열처럼 여러 원소를 저장하지만, 배열과는 다르게 위의 네 가지 유형의 자료구조는 정적 메모리 할당이 아닌 동적 메모리 할당을 하게 된다.


    [주요 인터페이스 간의 상속 관계]

    [주요 인터페이스의 특징]


Exception

[예외 클래스의 계층 구조]
자바에서는 오류를 ErrorException으로 나누었고 이들을 클래스로 구현하여 처리하도록 하였다.

에러(error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
  • JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성하고서 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해준다.

  • 자바에서 다루는 모든 예외 오류는 Exception 클래스에서 처리한다. 그리고 아래의 Exception 클래스 트리 구조를 보면 파랑색과 붉은색으로 색깔별로 구분됨을 볼 수 있는데, 이것이 컴파일 에러와 런타임 에러를 따로 클래스로 구분했기 때문이다.

    Exception 클래스는 다시 RuntimeException(런타임 에러)그 외의 자식 클래스 그룹(컴파일 에러)으로 나뉘게 된다.

  • Exception 및 하위 클래스 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 컴파일시 발생하는 예외
    • 존재하지 않는 파일의 이름을 입력 (FileNotFoundException)
    • 실수로 클래스의 이름을 잘못 기재 (ClassNotFoundException)
    • 입력한 데이터 형식이 잘못된 경우 (DataFormatException)

  • RuntimeException 클래스 : 프로그래머의 실수로 발생하는 예외
    • 배열의 범위를 벗어남 (IndexOutOfBoundsException)
    • 값이 null인 참조 변수의 멤버를 호출 (NullPointerException)
    • 클래스 간의 형 변환을 잘못함 (ClassCastException)
    • 정수를 0으로 나누는 산술 오류 (ArithmeticException)
Sample sample = new Sample();

try {
    sample.addSample(100);
    sample.printSample(); // 만일 이 메서드를 실행하는데 에러가 나버리면 !
   
} catch (Exception e) {
	// ... catch 문의 코드가 실행되고
} finally {
	 sample.shouldBeRun(); // 에러가 나든 안나든 무조건 finally 문은 실행된다.
}
  • 예외가 발생한 경우에는 try → catch → finally 의 순서로 실행되고, 예외가 발생하지 않는 경우에는 try → finally 의 순으로 실행된다고 보면 된다.

Checked Exception & Unchecked Exception

자바의 예외(Exception)는 컴파일 에러와 런타임 에러로 구분된다.
그런데 또다시 예외 종류로서 Checked ExceptionUnchecked Exception 로 나뉜다.

  • Checked Exception컴파일 예외클래스들을 가리키는 것이고, Unchecked Exception런타임 예외클래스들을 가리키는 것이다. (코드적 관점에서 예외 처리 동작을 필수 지정 유무에 따라 나뉘기 때문에)
  • Checked Exception은 체크 하는 시점이 컴파일 단계이기 때문에, 별도의 예외 처리를 하지 않는다면 컴파일 자체가 되지 않는다.
  • Checked Exception이 발생할 가능성이 있는 메소드라면 반드시 로직을 try - catch로 감싸거나 throws로 던져서 처리해야 한다.
  public class MainClass04 {
	public static void main(String[] args) { //throws InterruptedException 쓰면 try문 안해도 오류 x
		System.out.println("main 메소드가 시작 되었습니다.");		
		try {			
			/*
			 *  실행의 흐름을 스레드라고 하는데 스레드를 임의로 5초동안 잡아두기 
			 *  컴파일시에 발생하는 Exception(RuntimeException을 상속받지 않은 Exception)
			 *  이 발생하기 때문에 반드시 try~catch 블럭으로 예외 처리를 해야 한다. 
			 */			
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}		
		//일정 시간 실행의 흐름을 잡아놓을 수 있다
		//스레드 (Thread) 작업단위
		System.out.println("main 메소드가 종료 되었습니다.");
	}
}

  • Unchecked Exception의 경우는 명시적인 예외 처리를 하지 않아도 된다.

예외 발생시키기(throw) & 예외 떠넘기기(throws)

[ 예외 발생시키기(throw) ]

  • 만일 프로그램적으로 에러가 아니라도 로직상 개발자가 일부러 에러를 내서 로그에 기록하고 싶은 상황이 올 수 있다. 자바에서는 throw 키워드를 사용하여 강제로 예외를 발생시킬 수 있다.

    사용 예시
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try {
            Scanner s = new Scanner(System.in);
            System.out.print("음수를 제외한 숫자만 입력하세요 : ");
            int num = s.nextInt(); // 사용자로부터 정수를 입력 받음
            if (num < 0) {
                // 만일 사용자가 말을 안듣고 음수를 입력하면 강제로 에러 발생 시켜버리기!!
                throw new ArithmeticException("왜 하지말라는 짓을 하시는 거죠? ㅡㅡ"); // ArithmeticException 예외 클래스 객체를 생성해 catch문으로 넘겨버린다고 생각하며 된다
            }
            System.out.println("음수를 입력하지 않으셨군요. 감사합니다");
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        } finally {
            System.out.println("프로그램을 종료합니다");
        }
    }
}

[ 예외 떠넘기기(throws) ]

  • 예외가 발생할 수 있는 코드를 작성할 때 try - catch 블록으로 처리하는 것이 기본이지만, 경우에 따라서는 다른 곳에서 예외를 처리하도록 호출한 곳으로 예외를 떠넘길 수도 있다.
  • 이때 사용하는 키워드가 throws이다. throws메소드 선언부 끝에 작성되어 메소드에서 예외를 직접 처리(catch)하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다.
예외를 발생시키는 키워드는 throw 고 예외를 메서드에 선언하는 키워드는 throws 이다.

사용 예시

void method() throws Exception, Exception2, ... {	
    에러발생코드; // 예외가 발생하면 현 메소드를 호출한 쪽으로 올라간다.
}
----------------------------------------------------------------------------
public class Main {
    public static void main(String[] args) {
        try {
            method1();
            method2();
            method3();
        } catch (ClassNotFoundException | ArithmeticException | NullPointerException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void method1() throws ClassNotFoundException {
        throw new ClassNotFoundException("에러이지롱");
    }

    public static void method2() throws ArithmeticException {
        throw new ArithmeticException("에러이지롱");
    }

    public static void method3() throws NullPointerException {
        throw new NullPointerException("에러이지롱");
    }
}
  • 예외클래스를 메서드의 throws에 명시하는 것은 이곳에서 예외를 처리하는 것이 아니라 자신을 호출한 메서드에게 예외를 전달하여 예외 처리를 떠맡기는 것이다. 또한 예외를 전달받은 메서드가 또다시 자신을 호출한 메서드에게 전달할 수 있다. 이런 식으로 계속 호출 스택에 있는 메서드들을 따라 전달되다가, 제일 마지막에 있는 main 메소드에서 throws를 사용하면 가상머신에서 처리된다.

0개의 댓글