본문 바로가기

WINK-(Web & App)/JAVA 스터디

[2024-2 Java 스터디] 김태일 #7주차

반응형

07-4 예외 처리

1. try ~ catch 문

- 기본구조

- try문 안의 문장을 수행하는 도중에 예외가 발생하면 예외에 해당되는 catch문 수행

try {
    <수행할 문장 1>;
    <수행할 문장 2>;
    ...
} catch(예외1) {
    <수행할 문장 A>;
    ...
} catch(예외2) {
    <수행할 문장 a>;
    ...
}

 

2. finally

- 예외 발생 여부에 상관없이 무조건 실행

public class Sample {
    public void shouldBeRun() {
        System.out.println("ok thanks");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        int c;
        try {
            c = 4 / 0;
        } catch (ArithmeticException e) {
            c = -1;
        } finally {
            sample.shouldBeRun();  // 예외에 상관없이 무조건 수행
        }
    }
}

 

3. 예외 활용하기

- RuntimeException: 실행 시 발생하는 예외

- Exception: 컴파일 시 발생하는 예외

class FoolException extends Exception {
}

public class Sample {
    public void sayNick(String nick) {
        try {
            if("바보".equals(nick)) {
                throw new FoolException();    //예외 발생
            }
            System.out.println("당신의 별명은 "+nick+" 입니다.");
        }catch(FoolException e) {              
            System.err.println("FoolException이 발생했습니다.");     //예외 처리
        }
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.sayNick("바보");
        sample.sayNick("야호");
    }
}

 

4. 예외 던지기

- throws 구문을통해 예외 위로 보내기

class FoolException extends Exception {
}

public class Sample {
    public void sayNick(String nick) throws FoolException {   //예외 던지기 -> try..catch문 삭제
    	if("바보".equals(nick)) {
            throw new FoolException();
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        try {
            sample.sayNick("바보");    // catch문으로 바로 넘어감
            sample.sayNick("야호");    // 수행되지 않음
        } catch (FoolException e) {
            System.err.println("FoolException이 발생했습니다."); //FoolException이 발생했습니다.출력
        }
    }
}

 

 throw와 throws의 차이

  • throw : 메서드 내에서 예외를 발생시키는 데 사용
  • throws : 메서드 선언부에서 사용, 해당 메서드가 처리하지 않은 예외를 호출자에게 전달함을 나타냄

 

07-5 스레드

- 한 프로세스 내에서 두 가지 또는 그 이상의 일을 동시에 수행 가능

public class Sample extends Thread {
    int seq;

    public Sample(int seq) {
        this.seq = seq;
    }

    public void run() {
        System.out.println(this.seq + " thread start.");  // 쓰레드 시작
        try {
            Thread.sleep(1000);  // 1초 대기한다.
        } catch (Exception e) {
        }
        System.out.println(this.seq + " thread end.");  // 쓰레드 종료 
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {  // 총 10개의 쓰레드를 생성하여 실행한다.
            Thread t = new Sample(i);
            t.start();
        }
        System.out.println("main end.");  // main 메서드 종료
    }
}

출력문을 보았을때 순서가 일정하지 않은 것을 보면 스레드는 순서에 상관없이 동시에 실행된다 것을 알 수 있음

 

1. Join

- 모든 스레드가 종료된 후에 main 메서드를 종료하고 싶을 때 사용

import java.util.ArrayList;

public class Sample extends Thread {
    int seq;
    public Sample(int seq) {
        this.seq = seq;
    }

    public void run() {
        System.out.println(this.seq+" thread start.");
        try {
            Thread.sleep(1000);
        }catch(Exception e) {
        }
        System.out.println(this.seq+" thread end.");
    }

    public static void main(String[] args) {
        ArrayList<Thread> threads = new ArrayList<>();
        for(int i=0; i<10; i++) {
            Thread t = new Sample(i);
            t.start();
            threads.add(t);
        }

        for(int i=0; i<threads.size(); i++) {
            Thread t = threads.get(i);
            try {
                t.join(); // t 쓰레드가 종료할 때까지 기다린다.
            }catch(Exception e) {
            }
        }
        System.out.println("main end.");
    }
}

 

2. Runnable

- thread 클래스를 extends 하는 것 대신 runaable 인터페이스를 implements

- 인터페이스의 경우 다른 클래스 상속이 가능하므로 유연함

import java.util.ArrayList;

public class Sample implements Runnable {
    int seq;
    public Sample(int seq) {
        this.seq = seq;
    }

    public void run() {
        System.out.println(this.seq+" thread start.");
        try {
            Thread.sleep(1000);
        }catch(Exception e) {
        }
        System.out.println(this.seq+" thread end.");
    }

    public static void main(String[] args) {
        ArrayList<Thread> threads = new ArrayList<>();
        for(int i=0; i<10; i++) {
            Thread t = new Thread(new Sample(i));
            t.start();
            threads.add(t);
        }

        for(int i=0; i<threads.size(); i++) {
            Thread t = threads.get(i);
            try {
                t.join();
            }catch(Exception e) {
            }
        }
        System.out.println("main end.");
    }
}

 

 

07-6 함수형 프로그래밍

1. 람다

- 익명 함수

- 실제 클래스 없이도 객체 생성 가능

interface Calculator {
    int sum(int a, int b);
}

class MyCalculator implements Calculator {
    public int sum(int a, int b) {
        return a+b;
    }
}

public class Sample {
    public static void main(String[] args) {
        MyCalculator mc = new MyCalculator();
        int result = mc.sum(3, 4);
        System.out.println(result);  // 7 출력
    }
}
interface Calculator {
    int sum(int a, int b);
}

public class Sample {
    public static void main(String[] args) {
        Calculator mc = (int a, int b) -> a +b;  //인터페이스에 이미 a,b가 정의되어 있으므로 int 생략 가능
        int result = mc.sum(3, 4);
        System.out.println(result);
    }
}  // 람다 적용 코드

 

2. 스트림

- 데이터를 필터링 과정을 통해 여러번 변경되어 반환

import java.util.*;

public class Sample {
    public static void main(String[] args) {
        int[] data = {5, 6, 4, 2, 3, 1, 1, 2, 2, 4, 8};

        // 짝수만 포함하는 ArrayList 생성
        ArrayList<Integer> dataList = new ArrayList<>();
        for(int i=0; i<data.length; i++) {
            if(data[i] % 2 == 0) {
                dataList.add(data[i]);
            }
        }

        // Set을 사용하여 중복을 제거
        HashSet<Integer> dataSet = new HashSet<>(dataList);

        // Set을 다시 List로 변경
        ArrayList<Integer> distinctList = new ArrayList<>(dataSet);

        // 역순으로 정렬
        distinctList.sort(Comparator.reverseOrder());

        // Integer 리스트를 정수 배열로 변환
        int[] result = new int[distinctList.size()];
        for(int i=0; i< distinctList.size(); i++) {
            result[i] = distinctList.get(i);
        }
    }
}
import java.util.Arrays;
import java.util.Comparator;
//스트림 사용 코드
public class Sample {
    public static void main(String[] args) {
        int[] data = {5, 6, 4, 2, 3, 1, 1, 2, 2, 4, 8};
        int[] result = Arrays.stream(data)  // IntStream을 생성한다.
                .boxed()  // IntStream을 Stream<Integer>로 변경한다.
                .filter((a) -> a % 2 == 0)  //  짝수만 뽑아낸다.
                .distinct()  // 중복을 제거한다.
                .sorted(Comparator.reverseOrder())  // 역순으로 정렬한다.
                .mapToInt(Integer::intValue)  // Stream<Integer>를 IntStream으로 변경한다.
                .toArray()  // int[] 배열로 반환한다.
                ;
    }
}
  1. Arrays.stream(data)로 정수 배열을 IntStream으로 생성한다.
  2. .boxed()로 IntStream을 Integer의 Stream으로 변경한다. 이렇게 하는 이유는 뒤에서 사용할 Comparator.reverseOrder 메서드는 원시 타입인 int 대신 Integer를 사용해야 하기 때문이다.
  3. .filter((a) -> a % 2 == 0)로 짝수만 필터링한다. 이때 사용한 (a) -> a % 2 == 0 구문은 앞에서 공부한 람다 함수이다. 입력 a가 짝수인지를 조사하는 람다 함수로 짝수에 해당되는 데이터만 필터링한다.
  4. .distinct()로 스트림에서 중복을 제거한다.
  5. .sorted(Comparator.reverseOrder())로 역순으로 정렬한다.
  6. .mapToInt(Integer::intValue)로 Integer의 Stream을 IntStream으로 변경한다. 왜냐하면 최종적으로 int[] 타입의 배열을 리턴해야 하기 때문이다.
  7. .toArray()를 호출하여 IntStream의 배열인 int[] 배열을 리턴한다.

 

7주차 퀴즈

 

객관식 문제

1. Java에서 try 블록에 포함할 수 없는 것은 무엇인가요?

답 : B) catch 블록

 

2. finally 블록의 실행 시점은 언제인가요?

답 : try 블록 이후 항상 실행된다

 

3. 다음 코드에서 출력 결과는?

public class Test {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic Exception");
        } finally {
            System.out.println("Finally Block");
        }
    }
}

답 : A) Arithmetic Exception

      B) Finally Block

 

4. 다음 코드에서 catch 블록이 처리할 수 있는 예외는?

public class Test {
    public static void main(String[] args) {
        try {
            String s = null;
            System.out.println(s.length());
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic Exception");
        }
    }
}

답 : C) 아무것도 처리하지 않음

 

5. throw와 throws의 차이는 무엇인가요?

B) throw는 예외 발생, throws는 선언

 

6. catch 블록에서 예외 처리 후 프로그램이 실행을 계속하기 위해 필요한 것은?

답 : C) 올바른 예외 처리가 이루어짐

 

7. finally 블록이 실행되지 않을 경우는 언제인가요?

답 : C) JVM이 강제 종료될 때

 

8. 다음 코드에서 출력 결과는?

public class Test {
    public static void main(String[] args) {
        try {
            System.out.println("Try Block");
            return;
        } finally {
            System.out.println("Finally Block");
        }
    }
}

답 : A) Try Block

      B) Finally Block

 

9. 다음 코드에서 출력 결과는?

public class Test {
    public static void main(String[] args) {
        try {
            throw new Exception();
        } finally {
            System.out.println("Finally Block");
        }
    }
}

답 : C) Finally Block Exception 발생

 

10. 다음 코드에서 출력 결과는?

public class Test {
    public static void main(String[] args) {
        try {
            throw new RuntimeException();
        } catch (Exception e) {
            System.out.println("Catch Block");
        } finally {
            System.out.println("Finally Block");
        }
    }
}

답 : A) Catch Block

      B) Finally Block

 

11. Java 8에서 스트림의 주요 특징이 아닌 것은?

답 : B) 데이터 변경 가능

 

12. 람다 표현식의 문법 중 올바르지 않은 것은?

답 : D) (x, y) -> { return; x + y; }

 

13. 다음 코드에서 출력 결과는?

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Stream.of(1, 2, 3, 4)
              .filter(x -> x % 2 == 0)
              .forEach(System.out::print);
    }
}

 답 : B) 24

 

14. 람다 표현식과 메서드 참조의 차이는?

답 : C) 람다는 메서드 참조보다 유연성이 높다

 

15. 다음 스트림 코드의 출력 결과는?

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int sum = IntStream.range(1, 5).reduce(0, Integer::sum);
        System.out.println(sum);
    }
}

답 : B) 15

 

16. Java의 함수형 프로그래밍에서 "고차 함수"란 무엇인가요?

답 : B) 다른 함수를 매개변수로 받거나 반환하는 함수

 

17. 다음 코드는 어떤 스트림 연산을 사용하고 있나요?

Stream.of("a", "b", "c")
      .map(String::toUpperCase)
      .forEach(System.out::println);

답 : B) 매핑

 

코드 실행 결과 예측 문제 (5개)

1.

import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        Function<String, Integer> length = String::length;
        System.out.println(length.apply("Lambda"));
    }
}

답 : B) 6

 

2.

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c");
        list.stream()
            .filter(x -> x.equals("b"))
            .forEach(System.out::print);
    }
}

답 : B) b

 

3.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.range(1, 5)
                 .map(x -> x * x)
                 .forEach(System.out::print);
    }
}

답 : A) 14916

 

4.

import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional<String> optional = Optional.of("Lambda");
        System.out.println(optional.orElse("Default"));
    }
}

답 : A) Lambda

 

5.

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Stream.of("A", "B", "C")
              .filter(s -> s.startsWith("B"))
              .forEach(System.out::println);
    }
}

답 : B) B

 

코딩 테스트

1.  https://www.acmicpc.net/problem/2920 - 브2

 

2. https://www.acmicpc.net/problem/1259- 브1

 

반응형