1. compareTo() 메서드를 오버라이딩 해준다. 최신순(내림차순)으로 정렬하기 위해 리턴 값에 -1을 곱해줬다.

public class CompletedOrder extends Order implements Comparable<CompletedOrder> {
    String completiontime;

    CompletedOrder(){
    }

    CompletedOrder(Order order){
        super(order.orderNum, order.orderList, order.totalPrice, order.time, order.request);
        this.completiontime = getTime();
    }

    @Override
    public String toString() {
        return "\n1. 대기번호 : " + this.orderNum + "\n2. 주문 상품 목록 : " + this.orderList +"\n3. 주문 총 가격 : " + this.totalPrice + "W\n4. 요청사항 : " + this.request + "\n5. 주문 일시 : " + this.time + "\n6. 완료 주문 일시 : " +this.completiontime+ "\n";
    }

    @Override
    public int compareTo(CompletedOrder o) {
        return this.completiontime.compareTo(o.completiontime) * -1; // 최신순 정렬
    }
}

 

2. sort 메서드로 정렬해 준다. 이때 정렬 기준에 오버라이딩한 compareTo를 넣어준다.

    public void printRecentOrder(){
        System.out.println("[ 최근 완료된 주문 ]");
        
        Collections.sort(completedOrders, CompletedOrder::compareTo); // 주문 완료 처리된 순서대로 정렬

        int SIZE = completedOrders.size();
        if(SIZE >= 3){
            for (int i = 0; i <3; i++){
                System.out.println(completedOrders.get(i));
            }
        } else {
            for (CompletedOrder o : completedOrders){
                System.out.println(o);
            }
        }
    }

 

'TIL > WEEK4' 카테고리의 다른 글

팀 과제 키오스크 관리 프로젝트  (0) 2023.06.07

지난번 개인 과제 키오스크에서 기능을 추가하는 팀 프로젝트를 진행했다.

 

과제에서 요구한 추가 기능은 다음과 같다.

손님이 주문할 때 요청사항을 적는 기능

  • (개선) 주문 화면

         주문 시 요청사항 메시지를 입력할 수 있습니다. (20자 제한)

  • (신규) 주문 현황

          맨 위에 완료된 최근주문 3개를 출력한다.

          그 아래에 대기 중인 모든 주문 목록을 출력한다.

 

 

가게 주인이 주문 현황과 메뉴 목록을 추가, 삭제할 수 있도록 하는 기능

          0. 메인 메뉴

    • 메인 메뉴에서 아래 기능을 실행한다.
      • “1. 대기주문 목록”
      • “2. 완료주문 목록”
      • “3. 상품 생성”
      • “4. 상품 삭제”
    1. 대기주문 목록
    • 주문이 완료되어 처리 대기 중인 주문을 조회하고 완료처리 할 수 있다.
    • 주문 데이터 형식은 아래와 같다.
      1. 대기 번호
      2. 주문 상품 목록
      3. 주문 총 가격
      4. 요청 사항
      5. 주문 일시
      6. 날짜는 ISO 8601 형식으로 조합된 UTC 날짜 및 시간 예) 2016-10-27T 17:13:40+00:00

            2. 완료 주문 목록

      • 완료처리 했던 주문들을 모두 조회할 수 있다.
      • **[ 완료주문 데이터 ]**는 **[ 주문 데이터 ]**에 완료 일시를 추가로 가진다.
      • [ 완료주문 데이터 ]
        1. 대기 번호
        2. 주문 상품 목록
        3. 주문 총 가격
        4. 주문 일시
        5. 요청 사항
        6. 완료주문 일시
        7. 날짜는 ISO 8601 형식으로 조합된 UTC 날짜 및 시간 예) 2016-10-27T 17:13:40+00:00

               3. 상품 생성

      • 새로운 상품정보(메뉴, 이름, 설명, 가격)를 입력하여 생성할 수 있다.
      • 기존에 없는 메뉴라면 신규로 생성해 준다.
      • 새로 생성된 메뉴와 상품은 각각 유일한 메뉴 ID, 상품 ID 식별자를 가진다.

                4. 상품 삭제

      • 상품 ID를 가지고 기존 상품정보를 삭제할 수 있다.
      • 삭제이전에 주문된 주문정보에서는 삭제되지 않는다.

 

 

 

 

 

대기주문 목록을 담을 Order 클래스

인스턴스를 생성할 때 자동으로 주문일시(time)에 현재 시각을 넣을 수 있게 매개변수로 time을 받지 않는 생성자를 만들어줬다.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Order {
    int orderNum;
    String orderList;
    String time;
    double totalPrice;
    String request;

    Order(){}
    Order(int orderNum, String orderList, double totalPrice, String time, String request){
        this.orderNum = orderNum;
        this.orderList = orderList;
        this.totalPrice = totalPrice;
        this.time = time;
        this.request = request;
    }

    Order(int orderNum, String orderList, double totalPrice, String request){
        this.orderNum = orderNum;
        this.orderList = orderList;
        this.totalPrice = totalPrice;
        this.request = request;
        this.time = getTime();
    }

    public String getTime() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        return now.format(dateTimeFormatter);
    }

    @Override
    public String toString() {
        return "\n1. 대기번호 : " + this.orderNum + "\n2. 주문 상품 목록 : " + this.orderList +"\n3. 주문 총 가격 : " + this.totalPrice +"W\n4. 요청사항 : " + this.request + "\n5. 주문 일시 : " + this.time + "\n";
    }

}

 

 

 

주문 시 요청사항(request)을 손님에게 입력받은 뒤 장바구니(cart)에 담겨 있는 상품명들을 문자열로 연결해서(orderlist) 대기주문 목록(orders)에 넣어줬다. 주문번호와 총가격은 기존 프로젝트에 이미 있어서 그대로 가져왔다.

    private List<Item> cart;
    private List<Order> orders;
    
    
    public void addToWaiting(List<Item> cart){
        Scanner sc = new Scanner(System.in);
        System.out.println("요청 사항을 입력해주세요.");
        String request = sc.nextLine();

        String orderList = "";
        for(Item a : cart){
            orderList += a.name + ", ";
        }
        orderList = orderList.substring(0, orderList.length() - 2); // 맨 끝 , 제거
        orders.add(new Order(orderNumber, orderList, totalPrice, request));

    }

 

 

 

완료 주문 데이터는 대기 주문 데이터를 상속받아 주문 완료 일시(completiontime) 변수를 추가해 줬다. 또 완료 주문 목록을 최신순으로 정렬하기 위해 주문 완료 일시(completiontime)를 기준으로 비교하도록 compareTo를 오버라이딩 해줬다.

public class CompletedOrder extends Order implements Comparable<CompletedOrder> {
    String completiontime;

    CompletedOrder(){
    }

    CompletedOrder(Order order){
        super(order.orderNum, order.orderList, order.totalPrice, order.time, order.request);
        this.completiontime = getTime();
    }

    @Override
    public String toString() {
        return "\n1. 완료번호 : " + this.orderNum + "\n2. 주문 상품 목록 : " + this.orderList +"\n3. 주문 총 가격 : " + this.totalPrice + "W\n4. 요청사항 : " + this.request + "\n5. 주문 일시 : " + this.time + "\n6. 완료 주문 일시 : " +this.completiontime+ "\n";
    }
    @Override
    public int compareTo(CompletedOrder order) {
        return this.time.compareTo(order.completiontime);
    }


}

 

 

 

관리자가 완료처리할 대기주문 번호(idx)를 고르면 선택한 주문 데이터(co)를 완료 주문 리스트(completedOrders)에 추가하고 대기주문 목록(orders)에서 삭제했다.

    public void CompletedOrder(int idx){
        Order co = getOrder(idx);
        orders.remove(idx);
        completedOrders.add(new CompletedOrder(co));
    }

 

 

 

완료된 최근주문 3개를 출력하도록 내림차순으로 정렬한 뒤, 완료 주문 목록의 크기가 3 이상이면 세 개만 출력되게 하고 그 미만이면 전부 출력되게 했다.

private List<CompletedOrder> completedOrders;


public void printRecentOrder(){
        completedOrders.sort(Collections.reverseOrder());
        int SIZE = completedOrders.size();
        if(SIZE >= 3){
            for (int i = 0; i <3; i++){
                System.out.println(completedOrders.get(i));
            }
        } else {
            for (CompletedOrder o : completedOrders){
                System.out.println(o);
            }
        }
    }

 

 

 

그 아래 대기 중인 주문 모두를 출력하는 메서드는 다음과 같이 작성했다.

    public void printWaiting() {
        int SIZE = orders.size();
        System.out.println("\n대기주문 "+SIZE+"개\n");
        for (Order order : orders){
            System.out.println(order);
        }
    }

 

'TIL > WEEK4' 카테고리의 다른 글

객체 내 시간 요소 순으로 정렬하기  (0) 2023.06.08

아쉬운 점

주문 번호를 출력하려면 순서가 있어야 된다고 생각해서 ArrayList를 이용해 구현했는데 다른 컬렉션을 써봤으면 어땠을까 싶다. 과제의 필수 요구사항은 구현했으나 선택 요구사항은 구현하지 못했다. 내가 시도했던 선택 요구사항은 주문개수 기능 추가였는데,

위와 같이 유저가 장바구니에 같은 메뉴를 담으면 개수를 늘려서 출력하는 기능이다.

근데 ArrayList에서 중복 값을 찾으려면 Set이나 Map으로 변환을 해야 된다고 한다. 그래서 아예 처음부터 Map으로 설계했으면 어땠을까 싶다. 아직 Map이나 Set은 낯설어서 강의를 좀 더 듣고 연습도 해봐야겠다.

'TIL > WEEK3' 카테고리의 다른 글

예외처리  (0) 2023.05.31
개인과제 키오스크  (0) 2023.05.30

오늘의 삽질

오늘은 예외처리 강의를 들었는데 마침 지금 진행 중인 개인과제의 키오스크가 InputMismatchException을 다뤄보기 좋은 예제라 내가 짠 키오스크 코드로 예외처리에 도전해 봤다. 익셉션을 캐치하는 것까지는 잘 됐는데 catch 블락을 빠져나가면 프로그램을 그냥 끝내지 말고 다시 처음부터 실행시키고 싶어서 continue를 했더니 메인페이지에서 입력값은 안 받고 무한 루프되는 오류가 생겼다.. 

근데 마침 자바의 정석 8-7 연습문제가 이와 비슷한 케이스라 이걸로 먼저 연습해 보고 다시 도전해 봐야겠다.

 

연습문제 8-7

1~100 사이의 숫자를 맞추는 프로그램을 작성하시오. 예외처리를 해서 숫자가 아닌 값을 입력했을 때는 다시 입력을 받도록 하시오.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int answer = (int) (Math.random() * 100) + 1;
        int input = 0;
        int count = 0;

        do {
            count++;
            System.out.println("1과 100 사이의 값을 입력하세요 : ");

            // input = new Scanner(System.in).nextInt();
            try {
                Scanner sc = new Scanner(System.in);
                input = sc.nextInt();
            } catch (Exception e) {
                System.out.println("숫자를 입력해주세요.");
                continue;
            }

            if (answer > input) {
                System.out.println("더 큰 수를 입력하세요.");
            } else if (answer < input) {
                System.out.println("더 작은 수를 입력하세요.");
            } else {
                System.out.println("맞췄습니다.");
                System.out.println("시도 횟수는 " + count + "번입니다.");
                break;
            }

        } while (true);


    }
}

 

'TIL > WEEK3' 카테고리의 다른 글

개인과제 키오스크 완성  (0) 2023.06.01
개인과제 키오스크  (0) 2023.05.30

키오스크의 필수 기능(메뉴 선택, 취소, 장바구니에 넣기, 주문 취소, 주문완료)은 전부 구현했다.

 

오늘의 삽질!

 

1.  장바구니 상품 총 가격 오류

문제점 : 장바구니를 확인하고 다시 메인 메뉴로 돌아갔다 다시 장바구니 확인 창으로 돌아오면 장바구니에 넣어놓은 상품의 총가격이 두 배가 되는 오류가 발생

해결방안 : 총가격을 Order 클래스의 인스턴스 변수로 선언해놨더니 장바구니 확인 화면에서 나갔다가 다시 들어올 때마다 가격이 계속 더해져서 그런 오류가 발생했던 것 같다. 총가격을 지역변수로 바꾸고 메서드 첫줄에서 0으로 초기화 시켜줬더니 제대로 동작했다.

    public double getTotalPrice() {
        double totalPrice = 0.0;
        for(int i=0 ; i < order.size(); i++){
            totalPrice += order.get(i).price;
        }
        return totalPrice;
    }

 

2.  다중 중첩문의 continue

또 조건문과 반복문이 여러겹으로 중첩될 때 continue를 어떻게 써야 할지 잘 모르겠다. 사용자가 주문을 취소했을 때, 안쪽 루프에서 제일 바깥 루프로 가려고 메인 메뉴 루프에 라벨을 달고 continue 했더니 아래와 같은 경고가 떴다.

그래서 라벨을 지우고 그냥 컨틴뉴 해봤더니 이번엔 컨티뉴 자체가 불필요하단 경고창이 떴다;

아직 예외 처리부분 강의를 못 들었는데 아마 예외처리 강의에서 이런 부분도 다루지 않을까 싶다. 내일은 코딩보다 강의를 좀 들어봐야겠다.

 

 

'TIL > WEEK3' 카테고리의 다른 글

개인과제 키오스크 완성  (0) 2023.06.01
예외처리  (0) 2023.05.31

메서드 오버로딩

한 클래스 내의 같은 이름의 메서드를 여러 개 정의하는 것 (오버라이딩과 아무 관련 x)

 

오버로딩의 조건

  1.  메서드 이름이 같아야 한다.
  2.  매개변수의 개수 또는 타입이 달라야 한다.
  3.  반환 타입은 관계 없다.

 

생성자

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드로 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 한다.

연산자 new가 인스턴스를 생성하는 것이지 생성자는 인스턴스를 생성하지 않는다.

클래스에 정의된 생성자가 하나도 없을 때만 컴파일러가 기본 생성자를 제공한다.

 

생성자의 조건

  1.  생성자의 이름 = 클래스의 이름
  2.  리턴 값이 없으나 void를 붙이지 않는다.

 

생성자 this()

생성자에서 다른 생성자를 호출할 때 사용

다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.

class Car2 {
    String color;
    String gearType;
    int door;
    Car2(){
        this("white", "auto", 4); // Car2(String color, String gearType, int door) 호출
    };
    Car2(String color){
        this(color, "auto", 4); // Car2(String color, String gearType, int door) 호출
    };
    Car2(String color, String gearType, int door){
        this.color = color; // this.color(iv) 와 color(lv) 구별
        this.gearType = gearType;
        this.door = door;
    }
}

 

참조변수 this

인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.

인스턴스 메서드(생성자 포함)에서만 사용 가능 ➡️ 클래스 메서드(static 메서드)에서 사용 불가

지역변수와 인스턴스 변수를 구별하기 위해 사용한다.

위 코드에서 this.color는 String color;로 선언된 인스턴스 변수를 의미하고 color는 매개변수로 받은 지역변수 color를 의미한다.

참조변수 this와 생성자 this()는 아무런 관련이 없다.

'TIL > WEEK2' 카테고리의 다른 글

JAVA3 객체지향 프로그래밍1  (0) 2023.05.25
JAVA 2주차 배열과 컬렉션  (0) 2023.05.24
JAVA 2주차 조건문과 반복문  (0) 2023.05.23
JAVA 1주차  (0) 2023.05.22
  • 객체 : 속성(변수) + 기능(메서드) 모든 인스턴스를 대표하는 일반적 용어
  • 인스턴스 : 특정 클래스로부터 생성된 객체

 

클래스 변수와 인스턴스 변수

class MyVariables {
    int iv; // 인스턴스 변수
    static int cv; // 클래스 변수
    void method(){
        int lv = 0; // 지역 변수
    }   
}

인스턴스 변수 : 인스턴트가 생성 되었을 때 생성

클래스 변수 : 클래스가 메모리(RAM)에 로딩될 때 생성

지역 변수 : 메서드가 실행될 때 생성되었다가 종료시 자동으로 제거, 사용하기 전에 반드시 초기화해야 한다.

 

➡️ 인스턴스 변수는 인스턴트가 생성될 때 마다 생성되므로 인스턴스마다 다른 값을 가지지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.

 

 

기본형 매개변수와 참조형 매개변수

기본형 매개변수 : read만 할 수 있고 write 불가능

참조형 매개변수 :  read & write 가능

 

 

static 메서드와 인스턴스 메서드

static 메서드

  • 객체 생성 없이 클래스이름.메서드이름()으로 호출  예) Math.random()
  • 인스턴스 멤버와 관련없는 작업을 하는 메서드로 메서드 내에 인스턴스 변수나 메서드 사용 불가능 ➡️ 즉, 인스턴스 멤버(iv, im)를 사용하지 않는 메서드에 static을 붙인다!

 

static은 언제 붙여야 할까?

  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
  2. 클래스 변수(static 변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
  3. 클래스 메서드는(static 메서드)는 인스턴스 변수를 사용할 수 없다. 고로, 메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 것을 고려한다.

 

 

 

 

 

 

'TIL > WEEK2' 카테고리의 다른 글

JAVA3 객체지향 프로그래밍2  (0) 2023.05.26
JAVA 2주차 배열과 컬렉션  (0) 2023.05.24
JAVA 2주차 조건문과 반복문  (0) 2023.05.23
JAVA 1주차  (0) 2023.05.22

Array

배열은 크기를 지정해 놓고 생성해야 된다. 이처럼 크기를 고정해 놓고 생성하는 것을 정적 배열이라 한다.

int[] arr = new int[3]; // 크기를 지정해놓고 생성
arr[0] = 1;
System.out.println(arr[0]);

 

얕은 복사

int[] a = {1, 2, 3, 4};
int[] b = a;
b[0] = 3;
System.out.println(a[0]);

// 결과 : 3

이렇게 복사하면 배열의 주소값이 복사되어 a와 b가 같은 값을 가리키게 된다.

 

깊은 복사

clone() 메서드는 2차원이상 배열에서는 얕은 복사로 동작한다.

        int[] a = {1, 2, 3, 4};
        int[] b = a.clone();
        b[0] = 3;
        System.out.println("b[0] : " + b[0]);
        System.out.println("a[0] : " + a[0]);
        
// 결과 : b[0] : 3
//       a[0] : 1

 

그러므로, 배열을 복사할 때는 copyOf() 메서드를 이용한다.

// 깊은 복사 메서드

import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		// 2. Arrays.copyOf() 메서드
		int[] a = { 1, 2, 3, 4 };
		int[] b = Arrays.copyOf(a, a.length); // 배열과 함께 length값도 같이 넣어줍니다.
	}
}

 

Collection

 

 List

리스트는 크기가 가변적으로 늘어나는 동적배열이다.

        ArrayList<Integer> intList = new ArrayList<Integer>(); // 선언과 동시에 생성 크기 지정x

        intList.add(99);
        intList.add(50);
        intList.add(12); // 값이 추가되면서 크기가 늘어난다.

        System.out.println(intList.get(1));

        intList.set(1, 77); // 값을 수정
        System.out.println(intList.get(1));
        ArrayList<Integer> intList = new ArrayList<Integer>(); // 선언과 동시에 생성

        intList.add(99);
        intList.add(50);
        intList.add(12);
        
        System.out.println(intList.get(0));
        intList.remove(0);
        System.out.println(intList.get(0));
        
        결과 : 99
              50 // remove로 값을 제거하면 뒤에 있던 값들이 앞으로 땡겨진다.

 

 

Stack

값을 수직으로 쌓아놓고 넣었다가 빼서 조회하는 형식으로 데이터를 관리하는 자료형

LIFO “나중에 들어간 것이 가장 먼저 나온다(Last-In-First-out)” 

        Stack<Integer> intStack = new Stack<>();

        intStack.push(29);
        intStack.push(7);
        intStack.push(1004); // 값을 넣어줌

        while (!intStack.isEmpty()){
            System.out.println(intStack.pop()); // 맨 위에 값을 꺼낸다.
        }
        
// 결과 : 
1004
7
29

 

Set

순서가 없고 자료의 중복을 허용하지 않는 집합으로 생성자가 없어 생성자가 존재하는 HashSet 클래스를 이용해서 생성한다.

  • 선언 : Set<Integer> intSet 
  • 생성 : new HashSet<Integer>()
  • 추가 : intSet.add({추가할 값}) 
  • 조회 : intSet.get({조회 할 순번}) 
  • 삭제 : intSet.remove({삭제할 값}) 
  • 포함확인 : intSet.contains({포함확인 할 값}) - 해당값이 포함되어 있는지 boolean 값으로 응답

 

Map

key-value 구조로 key값은 중복을 허용하지 않는다.

  • 선언 : Map<String, Integer> intMap
  • 생성 : new HashMap<>()
  • 추가 : intMap.put({추가할 Key값},{추가할 Value값})
  • 조회 : intMap.get({조회할 Key값}) 
  • 전체 key 조회 : intMap.keySet() -  Map의 모든 Key를 모아서 Set 자료형으로 리턴
  • 전체 value 조회 : intMap.values() - Map의 모든 Value를 모아 Set 자료형으로 리턴
  • 삭제 : intMap.remove({삭제할 Key값})

 

 

연습

자료구조 요리 레시피 메모장 만들기

  • 입력값
    • 저장할 자료구조명을 입력합니다. (List / Set / Map)
    • 내가 좋아하는 요리 제목을 먼저 입력합니다.
    • 이어서 내가 좋아하는 요리 레시피를 한 문장씩 입력합니다.
    • 입력을 마쳤으면 마지막에 “끝” 문자를 입력합니다.
  • 출력값
    • 입력이 종료되면 저장한 자료구조 이름과 요리 제목을 괄호로 감싸서 먼저 출력해줍니다.
    • 이어서, 입력한 모든 문장 앞에 번호를 붙여서 입력 순서에 맞게 모두 출력해줍니다. 

 

내가 작성한 코드 일부

        switch (type) {
            case "List" :
                boolean flag = true;
                ArrayList<String> recipeArr = new ArrayList<>();

                while (flag) {
                    String recipe = sc.nextLine();

                    recipeArr.add(recipe);

                    if(recipe.equals("끝")) {
                        flag = false;
                    }
                }
                System.out.println("[ " + type + "으로 저장된 " + title + " ]");
                for(String item : recipeArr) {
                    System.out.println(item);
                }
                break;

 

정답 코드 일부

		switch (collectionName) {
			case "List":
				ArrayList<String> strList = new ArrayList<>();
				while (true) {
					// 한줄씩 입력받아서 strList 에 저장
					String text = sc.next();
					if (Objects.equals(text, "끝")) {
						break;
					}
					strList.add(text);
				}

				title = "[ List로 저장된 " + title + " ]";  // [ 제목 ]
				System.out.println(title);
				// strList 한줄씩 출력
				for (int i = 0; i < strList.size(); i++) {
					int number = i + 1;
					System.out.println(number + ". " + strList.get(i));
				}
				break;

알게 된 점

  • "끝"을 입력받았을 때 boolean 변수를 false로 바꿔서 while문을 빠져나왔는데 정답코드를 보니 그냥 간단하게 break를 쓰면 됐었다. 아직 break가 익숙지 않아서 이런 차이가 생긴 것 같다.
  • 처음에 레시피를 next()로 받았더니 레시피를 한 줄 단위가 아닌 단어로 받아와서 nextLine()으로 수정했다. 공백을 포함한 한 줄을 온전히 받으려면 nextLine 메서드를 써야겠다.

 

 

'TIL > WEEK2' 카테고리의 다른 글

JAVA3 객체지향 프로그래밍2  (0) 2023.05.26
JAVA3 객체지향 프로그래밍1  (0) 2023.05.25
JAVA 2주차 조건문과 반복문  (0) 2023.05.23
JAVA 1주차  (0) 2023.05.22

+ Recent posts