Java Day9

YDC·2025년 6월 17일

우테코8기

목록 보기
9/23

Day8 복습

long이란?

64비트(8바이트) 크기의 정수형 자료형
-2⁶³ ~ 2⁶³-1 범위의 정수를 저장할 수 있음

long을 사용했기때문에 Scanner도 nextLong사용

git이란?

  • 코드 변경 이력 버전을 관리할 수 있게 해주는 도구
  • 변경사항을 commit하고, 필요하면 이전 상태로 되돌릴 수 있음

브랜치란?

코드의 변경 이력을 독립적으로 실험하고 개발할 수 있게 해주는 분기점
지금까지의 커밋 이력을 그대로 복사한 후,그 위에서 자유롭게 실험하거나 개발할 수 있음

gitignore란?

.gitignore는 Git이 추적하지 않아야 할 파일을 지정하는 목록
처음에 ignore하는걸 잊어버리면 add가 추적하는걸 지워야지 github에 올라가지 않음 git rm --cache

리드미란? 프로젝트 소개서

README.md는 프로젝트의 첫인상이자 설명서

오늘의 학습 계획

1.백준 3문제 풀이

조건문

  • 1330 두 수 비교하기
  • 9498 시험 성적
  • 2753 윤년

2.Todo 실습 (PR 흐름 + merge)

  • main 브랜치
  • 기능 브랜치 생성 (feature/KeywordSearch)
  • 작업 & 커밋
  • push & PR 만들기 (GitHub에서)
  • main 최신화 (pull)
  • main에 merge & 브랜치 삭제

3.기능확장

  • 검색 기능 (Keyword Search)
  • For each사용 기능 추가
  • Stream사용 리팩토링
  • git rebase 병합 실습

1.백준 3문제 풀이

1.1330 조건문

문제

두 정수 A와 B가 주어졌을 때, A와 B를 비교하는 프로그램을 작성하시오.

입력

첫째 줄에 A와 B가 주어진다. A와 B는 공백 한 칸으로 구분되어져 있다.

출력

첫째 줄에 다음 세 가지 중 하나를 출력한다.

  • A가 B보다 큰 경우에는 '>'를 출력한다.
  • A가 B보다 작은 경우에는 '<'를 출력한다.
  • A와 B가 같은 경우에는 '=='를 출력한다.

제한

  • -10,000 ≤ A, B ≤ 10,000

예제 입력 1  1 2
예제 출력 <

예제 입력 2 10 2
예제 출력 2  >

예제 입력 3 55
예제 출력 3 ==

풀이

package condition;

import java.util.Scanner;
public class BOJ_1330_CompareNumbers {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        sc.close();
        if(a == b) {
            System.out.println("==");
        }else if (a>b){
            System.out.println(">");
        }else  {
            System.out.println("<");
        }
    }
}

기본적인 조건문 사용을 물어보는 문제 Scanner 사용후 close()해주는거 또는 nextLine()사용하는거 잊지 않기

2.9498 시험성적

문제

시험 점수를 입력받아 90 ~ 100점은 A, 80 ~ 89점은 B, 70 ~ 79점은 C, 60 ~ 69점은 D, 나머지 점수는 F를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 시험 점수가 주어진다. 시험 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.

출력

시험 성적을 출력한다.

예제 입력 1 100
예제 출력 1 A

풀이

package condition;
import java.util.Scanner;

public class BOJ9498_Grade {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int score = sc.nextInt();
        sc.close();
        if (score >= 90) {
            System.out.println("A");
        } else if (score >= 80) {
            System.out.println("B");
        } else if (score >= 70) {
            System.out.println("C");
        } else if (score >= 60) {
            System.out.println("D");
        } else{
            System.out.println("F");
        }

    }
}

조건문의 구조를 제대로 이해하고있는지 조건 순서에따라서 로직이 올바르게 작동하는지 단순 비교조건을 여러게 분기 처리 할 수 있는 지 확인

3.2753 윤년

문제

연도가 주어졌을 때, 윤년이면 1, 아니면 0을 출력하는 프로그램을 작성하시오.
윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때 또는 400의 배수일 때이다.
예를 들어, 2012년은 4의 배수이면서 100의 배수가 아니라서 윤년이다. 1900년은 100의 배수이고 400의 배수는 아니기 때문에 윤년이 아니다. 하지만, 2000년은 400의 배수이기 때문에 윤년이다.

입력

첫째 줄에 연도가 주어진다. 연도는 1보다 크거나 같고, 4000보다 작거나 같은 자연수이다.

출력

첫째 줄에 윤년이면 1, 아니면 0을 출력한다.

예제 입력 1 2000
예제 출력 1 1

예제 입력 2 1999

예제 출력 2 0

풀이

package condition;
import java.util.Scanner;

public class BOJ_2753_LeapYear {
    public static void main(String [] arg){
        Scanner sc = new Scanner(System.in);
        int year = sc.nextInt();
        sc.close();
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
            System.out.println(1);
        }else{
            System.out.println(0);
        }
    }
}

윤년의 정의 조건을 논리적으로 정확히 구현할 수 있나? 를 묻는 문제

개선하면 좋을 부분

System.out.println(isLeapYear ? 1 : 0);
삼항 연산자를 쓰면 출력과 조건이 명확히 분리됨

디버깅이나 테스트할 때 isLeapYear 변수만 봐도 이해됨

2.Todo 실습(PR흐름 + pull&rebase)

1.main 브랜치

git checkout main

현재 브랜치를 메인으로 변경

git pull origin main

원격저장소(origin)의 main 브랜치를 최신 상태로 로컬에 반영
최신 커밋까지를 가져온다는 의미

2.기능 브랜치 생성

git checkout -b feature/keyword-search

새로운 브랜치 생성 feature은 기능 추가라는 뜻 브랜치의 이름은 keyword-search

3.작업 & 컷밋

검색 기능 추가 및 커밋 완료

git add . git commit -m “”

4.puch & pr 만들기 (GitHub에서)

git push -u origin feature/keyword-search

github에 pr 작성

Add a title

Feat 검색 기능 추가

Add a description

TodoService에 searchBuKeyword, printSerachResult 메서드를 추가
Main 메뉴 case5에서 키워드 검색 기능 작동하도록 수정

5.main 최신화

git checkout main
git pull

6.main에 merge & 브랜치 삭제

GitHub에서
[Merge pull request] → [Confirm merge]
Delete branch - 브랜치 삭제

3.기능 확장

원하는 기능 입력 키워드가 포함된 할일 보여주기 대소문자 구분 없이 보여주기

방식 2가지

For-each 방식 ( 기초 방식) vs Stream 방식

Stream이란?

JAVA에서 데이터흐름(파이프라인)을 처리하기위한 방식
데이터를 반복 처리할 때, 더 선언적이고 간결하게 쓸 수 있게 도와주는 도구

메서드 역할

.stream() 리스트를 스트림으로 바꿈 (흐름 시작)
.filter() 조건에 맞는 값만 통과
.map() 데이터 변형 (예: 객체 → 이름 문자열)
.collect() 결과 모아서 리스트 등으로 반환

장점

  • 코드가 짧고, 의도가 명확함 (뭘 하고 싶은지 위주)
  • 중간에 여러 조건을 체이닝으로 연결 가능
  • 정렬, 변환, 중복 제거 등 다양한 작업도 한 줄로 처리 가능
  • 병렬 처리 가능 (.parallelStream())

단점

  • 초반에 배우기 어려움 (낯선 문법)
  • 디버깅이 살짝 번거로울 수 있음

for-each 방식

List<String> names = new ArrayList<>();
for (Person p : people) {
    if (p.getAge() > 18) {
        names.add(p.getName());
    }
}

반복하면서 조건 검사하고
결과 수집까지 우리가 직접 처리

for( x:y )?

향상된 for문(enhanced for-loop)
리스트나 배열을 편하게 반복할 때 쓰는 문법

for (자료형 변수 : 반복할 대상) {
    // 반복할 내용
}


for (int i = 0; i < list.size(); i++) {
    String s = list.get(i);
    System.out.println(s);
}

이걸 향상된 for문을 사용해서

List<String> list = List.of("a", "b", "c");

for (String s : list) {
    System.out.println(s);
}

이렇게 만들 수 있음

Stream 방식

List<String> names = people.stream()
    .filter(p -> p.getAge() > 18)
    .map(Person::getName)
    .collect(Collectors.toList());

사람 리스트를 → 나이 조건으로 거르고 → 이름만 뽑아서 → 리스트
절차는 신경 안 써도 됨 (우리가 직접 반복 안 돌림)

먼저 for each 문으로 작성후 후에 리팩토링 연습

2.For Each 사용 기능 추가

TodoService에 검색 메소드 추가

 // 검색 기능 추가

public List<Todo> searchByKeyword(String keyword) {
    List<Todo> result = new ArrayList<>();
    for (Todo t : todos){
        if (t.getTask().toLowerCase().contains(keyword.toLowerCase())){
            result.add(t);
        }
    }
    return result;
}

 //검색 결과 출력 메소드

public void printSearchResult(String Keyword){
    List<Todo> result = searchByKeyword(Keyword);
    if (result.isEmpty()) {
        System.out.println("검색된 일이 없습니다");
    }else{
        for (Todo t : result){
            System.out.println(t);
        }
    }
}

Main 수정

case 5:
    if (service.isEmpty()) {
        System.out.println("할일이 없습니다.");
    }else {
        System.out.print("검색할 키워드 입력: ");
        String task1 = sc.nextLine();
        service.printSearchResult(task1);
    }break;
case 6:
    TodoManager.saveTodosToFile(todos, "todos.json");
    System.out.println("종료합니다.");
    return;

6번 추가

private static void printMenu() {
    System.out.println("\n📋 메뉴를 선택해 주세요");
    System.out.println("1. 할 일 추가");
    System.out.println("2. 현재 할 일 확인");
    System.out.println("3. 할 일 완료 처리");
    System.out.println("4. 할 일 삭제");
    System.out.println("5. 검색");
    System.out.println("6. 종료.");
    System.out.print("번호를 입력해 주세요: ");
}

3.Steram 사용 리팩토링

1.새로운 브런치 생성

git catchout -b refactor/keyword-search

2.TodoService searchByKeyword Stream 사용 리팩토링

public List<Todo> searchByKeyword(String keyword) {
    return todos.stream()
            .filter(todo -> todo.getTask().toLowerCase().contains(keyword.toLowerCase()))
            .collect(Collectors.toList());
}

todos.stream todos 라는 리스트를 스트림으로 변환

 .filter(todo -> todo.getTask().toLowerCase().contains(keyword.toLowerCase()))

todos 안에 todo들중 검색한 게 포함이되어있것들만 필터링함

.collect(Collectors.toList());

그걸 모아서 리스트로 만듬

3.TodoService printSearchResult 리팩토링

public void printSearchResult(String Keyword){
    List<Todo> result = searchByKeyword(Keyword);
    if (result.isEmpty()) {
        System.out.println("검색된 일이 없습니다");
    }else{
        result.forEach(System.out::println);
        }
    }

.forEach(출력)

t -> System.out.println(t) 람다식을 -> System.out::println 이렇게 표현할 수 있음

4.git rebase 병합 실습

현재 새로운 브랜치 만들고 리팩토링까지 완료된 상황

리배이스 시도

리배이스란?
main: A---B---C
feature: D---E (← 네가 지금 만든 커밋들)
main: A---B---C---D'---E' ← 같은 작업인데 main 뒤에 새로 재작성됨

항목mergerebase
브랜치 병합 방식두 브랜치를 하나로 합침내 브랜치를 다시 붙이는 방식
커밋 이력분기점 + merge 커밋 생성일직선으로 정리됨
작업 흐름원래 작업 순서 유지마치 "나중에 작업한 것처럼" 커밋 재정렬
커밋 충돌 발생 가능성적음 (보수적)많을 수 있음 (재작성)
협업 시 주의점비교적 안전함푸시 전까지만 사용해야 안전함
사용 추천 상황공식 병합, 팀 작업 마무리개인 브랜치 정리, 커밋 이력 깔끔하게 정리하고 싶을 때

리베이스 실패

main 브랜치가 C 상태일 때,
브랜치를 새로 만듬 git checkout -b
그 위에서 커밋을 3개 함 D, E, F
이제 rebase main을 시도했더니 아무 일도 안 일어남
git rebase main은 커밋(D, E, F)을 최신 main 위에 덮어쓰겠다는 뜻이야.
근데 문제는 main 브랜치가 아직도 C 상태
내가 브랜치 땄을 때나 지금 rebase 할 때나→ main 브랜치에 아무 변화가 없었기 때문에 리베이스할 차이 자체가 없었음

즉 협업을 할때 필요한게 rebase !! 내가 메인에서 브랜치를 따서 작업을 할 동안
다른사람이 작업을하고 머지를해서 커밋이 올라가 내가 브랜치를 따온 시점이랑 메인의 커밋이 다를경우
그 커밋을 가져와서 히스토리를 깔끔하게 정리하고 머지 가능함!!
그래서 혼자 실습할려면

git checkout main
git pull origin main
git checkout -b ~~~
git checkout main
git add . 	
git commit -m “”
git push
git checkout ~~~
git rebase main
git push-f 이런식으로 진행해야함!

리뷰

오늘은 백준 다음 스텝으로 넘어갔다 조건문! 예전에는 윤년 문제가 너무 어려웠는데 또 다시 보니까 생각보다 너무 쉬웠다는거?
그래도 점점 레벨이 업되고 있다는 느낌이 들어서 기분이 좋았다
기능을 추가하고 깃을 더 활용해봤다 리베이스를 잘못 이해해서 실습에 실패했지만 협업할때는 잘 할 수 있을거같다
내일도 백준 문제풀고 지금 cs공부가 멈춰서 cs 공부 및 알고리즘 책 독서 그리고 카테고리 추가 기능하자! 오늘도 고생했다 나!

profile
초심자

0개의 댓글