본문 바로가기

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

[2024-2 Java 스터디] 김민서 #7주차

반응형
예외 처리

 

FileNotFoundException - 존재하지 않는 파일을 열려고 시도할 때

ArithmeticException - 0으로 나누려고 할 때

ArrayIndexOutOfBoundsException - 배열에서 아무것도 없는 곳을 가리켰을 때

등의 예외가 있다.

 

1. 예외 처리하기

try ~ catch 문 사용

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

 

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();  // 예외에 상관없이 무조건 수행된다.
        }
    }
}

 

 

2. 예외 활용하기

class FoolException extends RuntimeException {
}

public class Sample {
    public void sayNick(String nick) {
        if("바보".equals(nick)) {
            throw new FoolException();
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }

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

RuntimeException - 실행 시 발생하는 예외 (발생할 수도 있고 발생하지 않을 수도 있는 경우에 사용한다)

Exception - 컴파일 시 발생하는 예외 (예측이 가능한 경우에 사용한다)

 

3. 예외 던지기

throw - 메서드 내에서 예외를 발생시키는 데 사용

thorws - 메서드 선언부에서 사용되며, 해당 메서드가 처리하지 않은 예외를 호출자에게 전달함을 나타냄.

 

스레드

 

스레드를 이용하면 한 프로세스 내에서 두 가지 또는 그 이상의 일을 동시에 할 수 있다.

 

1. Thread 

// 10개의 스레드를 실행시키는 코드
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 메서드 종료
    }
}

 

 

2. 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.");
    }
}

ArrayList 객체인 threads를 만들고 생성된 객체를 threads에 저장, 각각의 스레드에 join 메서드를 호출

 

3. Runnable

Thread 클래스를 상속할 시에 Thread 클래스를 상속한 클래스가 다른 클래스를 상속할 수 없어 주로 Runnable 인터페이스를 사용한다

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.");
    }
}

 

 

함수형 프로그래밍

 

1. 람다

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;  // 람다를 적용한 코드
        int result = mc.sum(3, 4);
        System.out.println(result);
    }
}

익명함수, 일반적인 코드보다 훨씬 간단

* Calculator 인터페이스의 메서드가 1개 이상이면 람다 함수 사용 불가 -> 어노테이션을 사용하면 2개 이상의 메서드를 가진 인터페이스를 작성하는 것이 불가능

 

2. 람다 축약하기

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

public class Sample {
    public static void main(String[] args) {
        Calculator mc = (a, b) -> a +b;
        int result = mc.sum(3, 4);
        System.out.println(result);
    }
}

 

3. 스트림

데이터가 물결처럼 흘러가면서 필터링 과정을 통해 여러 번 변경되어 반환

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[] 배열로 반환한다.
                ;
    }
}

 


Quiz

객관식

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

답 - B) catch 블록

 

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

답 - C) 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");
        }
    }
}

답 - C) Arithmetic ExceptionFinally 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");
        }
    }
}

답 - C) Try BlockFinally Block

 

9.

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

답 - A) Finally BlockException 발생

 

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");
        }
    }
}

답 - C) Catch BlockFinally Block

 

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

답 - 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);
    }
}

답 - A) 10 

 

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

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

 

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

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

답 - B) 매핑

 

 

 

코드 실행 결과 예측

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

 

 

코딩테스트

백준 #2920

https://www.acmicpc.net/problem/2920

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int[] notes = new int[8];
        for (int i = 0; i < 8; i++) notes[i] = scanner.nextInt();
        
        String result = "mixed";
        if (notes[0] == 1 && notes[7] == 8) result = "ascending";
        else if (notes[0] == 8 && notes[7] == 1) result = "descending";

        for (int i = 1; i < 8; i++) {
            if ((notes[i] - notes[i - 1] != 1 && result.equals("ascending")) ||
                (notes[i] - notes[i - 1] != -1 && result.equals("descending"))) {
                result = "mixed";
                break;
            }
        }

        System.out.println(result);
    }
}

 

 

백준 #1259

https://www.acmicpc.net/problem/1259

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            String number = scanner.next();
            if (number.equals("0")) break;

            String reversed = new StringBuilder(number).reverse().toString();
            System.out.println(number.equals(reversed) ? "yes" : "no");
        }
    }
}
반응형