[TIL] 10일차 _ Java 문법 종합반 #5 & 계산기 프로젝트 #3

Seoyeon Lee·2025년 10월 17일

Today I Learned ...

오늘은 코드카타 알고리즘과 SQL 3번 문제를 풀고, Java 문법 종합반 강의를 마무리했다!
그리고, 계산기 프로젝트의 Lv.3를... 시작했다.


🗒️ 코드카타 #3

오늘 진행한 SQL 문제distinct 키워드를 사용해 중복된 값을 제거한 후, 데이터의 개수를 출력하는 것이었다.
이 내용도 사전캠프를 통해 다뤄보았기에 큰 어려움 없이 풀 수 있었다.

그리고, 알고리즘 문제는 어제의 내용과 이어서 나눗셈을 진행하는 메서드를 만드는 것이었다.
사실 어제 했던 내용에서 곱셈 기호만 나눗셈 기호로 바꾸면 되었기에 별다른 어려움 없이 풀 수 있었다.

각각의 문제와 풀이는 깃허브를 통해 업로드해두었다.
GitHub 보러가기


📚 4강 _ 자바 개념 확장(2)

4강의 남은 내용은 람다와 스트림, 쓰레드에 관한 내용이었다.

첫 번째로 람다(Lambda)란 익명 클래스를 더 간결하게 표현하는 문법인데,
이때 익명 클래스란 이름이 없는 클래스, 즉 별도의 파일 없이 코드 내에서 일회성으로 정의해서 사용하는 클래스를 뜻한다.

@FunctionalInterface
public interface Calculator {
    int sum(int a, int b); // 추상 메서드
}

public class Main {
    public static void main(String[] args) {
    	// 람다 표현식
        Calculator calculator1 = (a, b) -> a + b;

        // 컴파일러가 알아서 익명클래스를 구현
        Calculator calculator1 = new Calculator() {
                @Override
                public int sum(int a, int b) {
                        return a + b;
                }
        };
	}
}

위 예시와 같이 람다 식을 작성하면, 컴파일 시점에 컴파일러가 람다 표현식을 보고 sum() 메서드를 가진 익명 클래스를 구현한다.
이는 Calculator에 추상 메서드가 하나 뿐이기에 컴파일러가 sum() 메서드일 것이라고 추론하여 진행된 것이다.
그래서 Calculator에 메서드를 1개만 가지도록 하는 것이 좋고, 이를 위해 @FunctionalInterface(함수형 인터페이스)를 붙여서 사용하는 것이다.

두 번째로 스트림(Stream)이란 데이터를 효율적으로 처리할 수 있도록 하는 것이고, 앞서 다뤘던 컬렉션과 함께 자주 사용한다.
for문을 통해서도 비슷한 작동을 하도록 만들 수 있지만, 스트림을 활용하면 훨씬 더 간결하게 다룰 수 있다.

// 1. 데이터 준비: 스트림 생성
Stream<Integer> stream = arrayList.stream();
// 2. 중간 연산 등록: 각 요소를 10배로 변환 로직 등록
Stream<Integer> mappedStream = stream.map(num -> num * 10);
// 3. 최종 연산: 최종 결과 리스트로 변환
List<Integer> ret2 = mappedStream.collect(Collectors.toList());

// -> 한 줄로 표현 가능
List<Integer> ret2 = arrayList.stream() // 1. 데이터 준비
    .map(num -> num * 10)               // 2. 중간 연산 등록
    .collect(Collectors.toList());  // 3. 최종 연산

스트림은 3가지 단계로 처리가 된다.
먼저는 데이터 준비 단계인데, 이때는 컬렉션을 스트림으로 변환한다.
두 번째로 중간 연산 등록 단계에서는 데이터를 변환하거나 필터링하는 등의 작업을 수행한다.
마지막으로 최종 연산 단계에서는 최종 처리와 데이터를 변환하는 작업을 수행한다.

마지막으로 쓰레드(Thread)는 프로그램 내에서 독립적으로 실행되는 하나의 작업 단위이다.

쓰레드는 한 번에 하나의 작업만 처리하는 싱글 쓰레드(Single Thread와 여러 작업을 병렬적으로 동시에 처리하는 멀티 쓰레드(Multi-Thread)로 나눌 수 있다.
멀티 쓰레드는 Thread 클래스를 상속받아 구현하면 된다.

쓰레드를 실행시킬 때는 run() 혹은 start()를 사용할 수 있는데,
run()은 현재 쓰레드에서 작업 내용을 실행시킨다면, start()는 새로운 쓰레드에서 run()을 실행시킨다.
join()을 통해 다른 쓰레드가 종료될 때까지 main 쓰레드를 기다리게 만들 수도 있다.

멀티 쓰레드를 만들 때, 클래스에 Thread 클래스를 상속시켜서 사용할 수도 있지만,
Runnable 인터페이스를 통해 쓰레드를 구현하는 것을 권장한다.
Thread 클래스에는 쓰레드 제어 로직이 있는데, 여기에 쓰레드 실행 로직이 결합되면 문제가 생겼을 때 유지 보수 작업이 쉽지 않을 수 있다.
그래서 실행 로직을 Runnable 인터페이스를 통해 별도의 구현체로 분리해주는 것이다.

자세한 설명과 실습 내용은 노션에 정리해두었다.
Notion 확인하기


🖥️ 계산기 프로젝트 #3

Lv.3 계산기에는 Enum 구현이 요구되는데, 이 내용은 강의에서 다루지 않아 개인적으로 학습해야 했다.

Enum(Enumeration, 열거형)은 관련된 상수 데이터들의 집합이다.
상수를 단순히 정수로 치부하지 않고, 독립된 특수한 클래스로 구분해서 관리한다.

Enum을 사용하면 코드가 단순해지고, 가독성이 좋아지게 된다.
또한, 허용 가능한 값들을 제한할 수도 있고, 구현 의도가 '열거'임을 나타낼 수도 있다.

// enum 선언하기
enum Week{
	MONDAY,TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

// enum 참조 : 변수를 선언해서 사용
Week monday = Week.MONDAY;

// enum에 데이터 저장하기(heap 영역에 저장)
Week today = null; // 참조 타입이기 때문에 null도 저장 가능
today = Week.SUNDAY;

위와 같은 방식으로 enum을 선언하고, 사용하고, 데이터를 저장할 수도 있다.
이때 enum의 열거 상수는 모두 대문자로 작성하는 것을 권고한다.

열거 객체의 문자열을 리턴하는 name() 메서드,
열거 객체의 순번을 리턴하는 ordinal() 메서드,
열거 객체를 비교해서 순번 차이를 리턴하는 compareTo() 메서드,
문자열을 입력받아서 일치하는 열거 객체를 리턴하는 valueOf(String name) 메서드,
모든 열거 객체들을 배열로 리턴하는 values() 메서드 등을 사용할 수 있다.

그리고, enum 매핑을 통해 상수에 고유한 값을 부여하거나 상수 메서드로 활용하여 상수의 상태와 행위를 한 곳에서 관리할 수 있다.

라고 구글링을 통해 enum에 대해 정리했지만, 완전히 이해한 것은 아니다...

그래서 오늘은 enum을 통해 4가지 연산기호를 처리할 수 있도록 구현하는 과정까지만 진행하였다.
근데 사실 enum에 관한 글들 중에 사칙연산 기호를 처리하는 enum에 대한 글이 있어서... 컨닝을 해버렸다.

enum은 아직... 한번 이해하고 다시 읽으면 또 이해가 되지 않아서...
조금 더 공부를 해봐야겠다.


🙃 오늘의 느낀점

공부하다가 머리가 터진 사람이 없을리가 없다...
계속계속 새로운 개념들을 자꾸 알려주니까... 머리에 더 이상 빈 공간이 없다...

profile
백엔드 개발자 지망생

0개의 댓글