프로그래밍언어 자바 Part-1

3. 자바 기본문법-2

이번 강좌에서는 자바 프로그램의 기본구조와 변수, 메서드, 연산자, 분기문등 기본 문법 요소를 배웁니다.

이 강의를 통해 자바언어의 구조를 이해하고 기본 문법을 활용해 기초적인 자바 프로그램을 작성하고 실행할 수 있습니다.



01: 조건문(Conditional statement)

조건문은 조건에 따라 프로그램을 수행하기 위해 사용합니다. 관계연산자와 함께 사용되며 if, switch 문이 대표적입니다.

예를 들어 아이디와 비밀번호를 넣고 로그인하는 경우 입력한 값과 DB에 저장되어 있는 값을 비교해 둘다 맞으면 로그인 성공 그렇지 않으면 실패 메시지를 출력하는 경우등이 조건문의 사용 예 입니다.

이 외에도 게임 프로그램에서 미사일 발사 버튼을 누르는 경우 남아있는 미사일이 0 이라면 발사가 되지 않거나 파워가 10 이하인 경우 서서히 추락하게 한다거나 하는 로직 구현에도 조건문이 사용됩니다.

즉, 프로그램에서 뭔가의 입력을 받아 입력된 값에 따라 동작을 다르게 하거나 특정 조건에 따라 처리되도록 하는 경우 조건문을 사용한다고 볼 수 있습니다.

대표적인 조건문은 if 이며 다양한 조건 구성을 위해 if ~ else if 등이 사용 됩니다. 또다른 조건문으로 switch 문을 들 수 있으며 switch 는 조건값에 따라 수행블럭을 구분해서 정의할 수 있습니다. 이 외 3항연산과 같이 참/거짓에 따른 간단한 조건연산을 수행할 수 있는 구문도 있습니다.

1) if 문

조건에 따라 코드 블럭을 수행 합니다.

if(조건식) {
    실행 코드 블럭
}
// if, else if
if(power < 10) {
    slowdown();
}
else if((power > 100) && (time <= 50) {
    gofaster();
}
else {
    go();
}

2) switch

조건값에 따른 처리 블럭을 구분해서 처리할 수 있도록 구조화한 구문으로 상황에 따라 if ~ else if 문의 대체가 가능합니다.

switch(입력 변수) {
    case 조건값: 실행 구문;break;
    ..
    default: 기본 실행 구문;
}

3) 3항연산

간단하게 구현할 수 있는 조건문으로 비교적 간단한 if ~ else 구문 처리에 적합 합니다.

조건? true인 경우 수행문장 : false인 경우 수행문장;
String result = (login)? "로그인성공":"로그인실패";

» 실습: 조건문 기본 실습 예제

실습개요

switch 문을 이영해 메뉴를 선택하고 선택된 메뉴에 따라 기능을 실행합니다. 각각의 메뉴 실행과정에서 if 문과 3항연산이 사용 됩니다.

소스코드

import java.util.Scanner;

    public class Conditional {
        void login() {
            Scanner scan = new Scanner(System.in);

            System.out.print("## 아이디를 입력하세요: ");		
            String uname = scan.next();

            System.out.print("# 비밀번호를 입력하세요: ");
            String pwd = scan.next();

            if(uname.equals("hong") && pwd.equals("1234")) {
            System.out.println("인증 확인!! -> 로그인 성공");
            }
            else {
            System.out.println("아이디나 비밀번호가 틀렸습니다.!!");
            }
        }

    void check() {
        int cnt = 10;
        String msg = cnt > 0? "새로운 쪽지가 있습니다.!!" : "새로운 쪽지가 없습니다.!!";
        System.out.println(msg);
    }

    public static void main(String[] args) {
        Conditional con = new Conditional();

        while(true) {
            System.out.printf("# 메뉴를 선택하세요 (1:로그인, 2:쪽지확인, x:종료) ==> ");
            Scanner scan = new Scanner(System.in);
            String sel = scan.next();

            switch(sel) {
            case "1": con.login();break;
            case "2": con.check();break;
            case "x": System.exit(0);
            default : System.out.println("잘못된 입력 입니다.!!");
            }	
        }
    }
}

실행결과(예시)

# 메뉴를 선택하세요 (1:로그인, 2:쪽지확인, x:종료) ==> 1
## 아이디를 입력하세요: hong
# 비밀번호를 입력하세요: 23454
아이디나 비밀번호가 틀렸습니다.!!
# 메뉴를 선택하세요 (1:로그인, 2:쪽지확인, x:종료) ==> 1
## 아이디를 입력하세요: hong
# 비밀번호를 입력하세요: 1234
인증 확인!! -> 로그인 성공
# 메뉴를 선택하세요 (1:로그인, 2:쪽지확인, x:종료) ==> 2
새로운 쪽지가 있습니다.!!
# 메뉴를 선택하세요 (1:로그인, 2:쪽지확인, x:종료) ==> x


02: 반복문(Loop statement)

특정 코드 블럭을 반복하기 위해 사용합니다. for, while 문이 대표적이며 보통 관계연산자와 함께 많이 사용 합니다.

특정 조건에 따라 동일한 작업을 반복해서 수행하기 위한 구문 입니다. 조건문과 함께 프로그램의 로직을 설계하는데 꼭 필요한 구문 입니다. 특정 문제 해결을 위해 처리 로직을 만들 수 있는데 이를 알고리즘이라 합니다. 그리고 알고리즘 구현에 조건문과 반복문이 주요 역할을 수행 합니다.

대표적인 반복문은 for, while, do ~ while 등이 있습니다. 모든 반복문은 조건을 벗어나는 조건이 잘못 설정된 경우 무한루프에 빠질수 있으므로 주의해야 합니다.

for(초깃값 ; 조건식 ; 증감식) {
    ...
}
for(변수 : 집합형데이터) {
    ...
}
while(조건식) {
    ...
}
do {
    ...
} while(조건식);

» 실습: 반복문 기본 예제

실습개요

반복문 종합 응용 예제 입니다.

소스코드

public class Loop {
    public static void main(String[] args) {
        int power = 13;
        String members[] = {"홍길동","김길동","김사랑","아무개"};

        // 0 ~ 9 까지 즉 10회 반복
        for(int i=0;i<10;i++) {
            System.out.println(i);
        }

        // 배열의 인덱스를 이용해 데이터 출력
        for(int i=0;i<10;i++) {
            System.out.println(members[i]);
        }

        // 배열 데이터 크기만큼 반복하면서 String 타입 데이터를 가지고 옴.
        for(String name : members) {
            System.out.println(name);
        }

        // power > 10 보다 큰 경우에는 go() 함수를 호출해 동작시키고 power를 1감소
        while(power > 10) {
            System.out.println("go");
            power--;
        }
        System.out.println("stop");
    }
}

실행결과

0
1
2
3..9 (생략됨)
홍길동
김길동
김사랑
아무개
go
go
go
stop


03: 배열(Arrays)

프로그램을 작성하는 과정에는 여러 데이터가 필요 합니다. 예를 들어 100명 학생의 성적을 처리한다고 할때 각각의 성적 값을 변수에 할당한다면 100개의 변수가 필요합니다. 이런경우 배열을 이용하면 하나의 변수명으로 100개의 데이터를 처리할 수 있게 됩니다.

배열은 컴퓨터 프로그램에서 데이터를 처리하기 위해 만든 구조중 하나로 대부분의 언어에 존재하며 개념도 비슷합니다. 배열의 경우 다소 불편한 부분들이 있기 때문에 실제 프로그램 구현에는 LIST, MAP 등의 자료구조가 사용 됩니다. 이들은 6.자료구조와 컬렉션프레임웍에서 자세히 배우게 됩니다.

배열의 특징

가장 대표적인 자료구조 입니다. 데이터를 순차적으로 저장해 0부터 시작하는 인덱스를 통해 접근할 수 있습니다.

배열 선언 및 데이터 사용

int scores[] = {95,100,87,91};
int[] scores = {95,100,87,91};
int[] scores = new int[4];
scores[2] = 90; // 3번째 요소(87)을 90으로 변경.

System.out.println(scores[0]);

배열의 주요 메서드

자바에서 배열을 다루기 위한 메서드는 Arrays 클래스에 정의되어 있습니다. 따라서 배열과 관련된 처리를 위해서는 Arrays 클래스의 메서드를 활용할 수 있습니다.

asList()

String[] cars = {"hyundai","bmw","benz","toyota"};
ArrayList car_list = Arrays.asList(cars);

toString()

System.out.println(cars);  // Object ID가 출력됨.
System.out.println(Arrays.toString(cars));  // ["hyundai","bmw","benz","toyota"]

sort()

Arrays.sort(cars);  // [benz, bmw, hyundai, toyota]
Arrays.sort(cars, Collections.reverseOrder());  // [toyota, hyundai, bmw, benz]
Arrays.sort(cars, 0,2); // [hyundai, toyota, bmw, benz]

copyOf()

// 앞의 마지막 예제 결과에 이어짐.
String[] cars_copied = Arrays.copyOf(cars);  //[hyundai, toyota, bmw, benz]
String[] cars_copied = Arrays.copyOfRange(cars, 0,2);   // [hyundai, toyota]

다차원 배열

다차원 배열은 하나이상의 배열을 포함하고 있는 배열의 구조를 말합니다.

객체지향 프로그래밍 개념이 정착하기 이전에는 복잡한 자료구조 처리를 위해 다차원 배열을 사용했습니다.

단순히 정형화된 구조의 복잡한 데이터를 기계적으로 처리하는 데이터 분석이나 주어진 데이터를 통해 프로그램을 구성하는 게임등에는 여전히 많이 사용되고 있으나 일반적인 프로그램 개발에는 2차원 배열 정도만 사용하고 있습니다.

다차원 배열을 사용하기 전에 객체지향 구조나 스트림 기반의 연산을 고려해 보는 것이 좋습니다.

예를 들어 5과목씩을 수강하는 학생들의 성적을 처리하기 위해 다음과 같이 2차원 배열을 만들 수 있습니다.

int[][] allScores = { {90,85,70,55,60},{96,88,81,91,75} ....};

만일 여기에 학과별로 구분을 추가한다면 다음과 같이 3차원 배열로 확장할 수 있습니다.

int[][][] allScores = { 
    {
        {90,85,70,55,60},
        {96,88,81,91,75},
        {96,88,81,91,75},
        {96,88,81,91,75}
    },
    {
        {91,82,73,54,65},
        {96,87,88,99,80},
        {91,82,83,94,75},
        {96,87,88,99,70}
    },
    {
        {92,83,74,55,66},
        {97,88,89,90,71},
        {92,83,84,95,76},
        {97,88,89,90,71}
    }
    ...    
};

» 실습: 배열 종합 실습 예제

실습개요

기본 배열과 Arrays 클래스의 메서드 활용, 다차원 배열 실습예제 입니다.

소스코드

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

public class Array {

    public static void main(String[] args) {
        // 1. Declare and initialize an array
        System.out.println("# 1. Declare and initialize an array");
        int[] scores = { 95, 100, 87, 91 };
        scores[2] = 90; // 3번째 요소(87)을 90으로 변경.

        System.out.println(scores);
        for (int i = 0; i < scores.length; i++) {
            System.out.println(scores[i]);
        }

        // 2. Arrays method: toString(), asList()
        System.out.println("\n# 2. Arrays method: toString(), asList()");
        String[] cars = { "hyundai", "bmw", "benz", "toyota" };
        List<String> car_list = Arrays.asList(cars);
        System.out.println(car_list);
        System.out.println(car_list.get(1));
        // car_list.add("ford"); error

        // 3. Arrays method: sort(array, Comparator), sort(array, int fromindex, int toindex)​
        System.out.println("\n# 3. Arrays method: sort(array, Comparator), sort(array, int fromindex, int toindex)");
        Arrays.sort(cars);
        System.out.println(Arrays.asList(cars));

        Arrays.sort(cars, Collections.reverseOrder());
        System.out.println(Arrays.asList(cars));

        Arrays.sort(cars, 0, 2);
        System.out.println(Arrays.asList(cars));

        // 4. Arrays method: copyOf, copyOfRange
        System.out.println("\n# 4. Arrays method: copyOf, copyOfRange");
        String[] cars_copied1 = Arrays.copyOf(cars, cars.length);
        System.out.println(Arrays.asList(cars_copied1));

        String[] cars_copied2 = Arrays.copyOfRange(cars, 0, 2);
        System.out.println(Arrays.asList(cars_copied2));

        // 5. Multiple Array
        System.out.println("\n# 5. Multiple Array");
        int[][][] allScores = {
                { { 90, 85, 70, 55, 60 }, { 96, 88, 81, 91, 75 }, { 96, 88, 81, 91, 75 }, { 96, 88, 81, 91, 75 } },
                { { 91, 82, 73, 54, 65 }, { 96, 87, 88, 99, 80 }, { 91, 82, 83, 94, 75 }, { 96, 87, 88, 99, 70 } },
                { { 92, 83, 74, 55, 66 }, { 97, 88, 89, 90, 71 }, { 92, 83, 84, 95, 76 }, { 97, 88, 89, 90, 71 } } };
        System.out.println(allScores[1][2][0]);
    }
}

실행결과

# 1. Declare and initialize an array
[I@6a6824be
95
100
90
91

# 2. Arrays method: toString(), asList()
[hyundai, bmw, benz, toyota]
bmw

# 3. Arrays method: sort(array, Comparator), sort(array, int fromindex, int toindex)
[benz, bmw, hyundai, toyota]
[toyota, hyundai, bmw, benz]
[hyundai, toyota, bmw, benz]

# 4. Arrays method: copyOf, copyOfRange
[hyundai, toyota, bmw, benz]
[hyundai, toyota]

# 5. Multiple Array
91


04: 키보드 입력과 로깅

키보드 입력

컴퓨터 프로그램의 기본 구조는 입력 -> 처리 -> 출력 의 과정으로 볼 수 있습니다. 프로그램에서 어떤 처리를 하기 위해서는 데이터가 입력되어야 하는데 대표적인 입력방법은 키보드를 통해 입력하는 것입니다.

입력에 대한 보다 자세한 내용은 7.입출력과 네트워크 프로그래밍 에서 배우게 됩니다. 여기서는 간단한 방법으로 키보드로 부터 데이터를 입력받는 방법을 배워봅니다.

표준 입출력

입출력 장치는 다양하게 있을 수 있으며 자바에는 가장 기본이 되는 입력장치와 출력장치를 표준 입출력 장치로 정의 하고 있습니다.

키보드는 표준입력 장치로 System.in 으로 정의 되어 있으며 표준 출력의 경우 System.out 로 정의되어 있습니다. 이들 객체는 각각 java.io.InputStream, java.io.PrintStream 클래스의 인스턴스 입니다.

java.util.Scanner

Scanner 클래스는 입력 스트림으로 부터 데이터를 읽어오기 위한 유틸리티 클래스 입니다. 스트림은 데이터 입출력을 위한 일종의 통로로 파일과 연결된 스트림을 사용하면 파일로 부터 데이터를 읽을 수 있고 네트워크와 연결된 스트림을 사용하면 네트워크 통신을 통해 데이터를 읽을 수 있는 개념 입니다.

사용하기전에 java.util 패키지를 import 해주어야 합니다.

기본 사용법은 다음과 같습니다.

Scanner scan = new Scanner(System.in);
String name = scan.next();
int num = scan.nextInt();

로깅

프로그램에서 기록을 위해 메시지를 남기는 것을 로깅이라고 합니다. 예를 들면 웹서버의 경우 모든 사용자의 접속 데이터를 서버 로그로 저장하고 있습니다. 또한 프로그램 수행과정에서 발생하는 각종 정보들과 에러 메시지 들도 참고를 위해 모두 기록 됩니다.

지금까지 예제에서 프로그램 동작을 확인하기 위해 System.out.println() 을 사용해 왔습니다. 이는 콘솔에 메시지를 출력하는 것으로 실제 우리가 사용하는 프로그램들은 GUI를 통해 화면에 메시지가 출력되므로 System.out.println()을 사용할 일이 없습니다.

프로그램의 결과 뿐만 아니라 변수의 값을 확인하거나 상태를 확인하기 위해 System.out.println()을 사용할 수 있습니다. 그러나 이렇게 단순하게 출력문을 사용하는 것은 체계적으로 기록을 남기거나 관리하기 어려운 문제가 있습니다.

예를들어 실제 프로그램 개발에는 로그 메시지들을 매일 새로운 파일에 저장하거나 파일의 용량이 일정크기 이상이 되면 다른 파일로 생성하고 3달이상 지난 로그들은 삭제한다던가 하는 작업들이 필요하게 됩니다.

로깅 프레임워크(Logging Framework)

로깅 프레임워크는 바로 앞의 문제점들을 해결하기 위한 소프트웨어로 log4j, slf4j, logback 등이 유명 합니다. 로거(Logger) 라고도 합니다.

일반적으로 프로그램에서는 다른 로거들과의 결합이 용이한 slf4j 를 사용하고 로깅 프레임워크로는 logback을 사용하는 추세 입니다. 각각의 로깅 솔루션에 대해서는 관련 자료들을 참고하기 바랍니다.

여기서는 로깅의 개념만 정리하고 자바의 기본 로거를 이용한 로그 관리 개념을 살펴 봅니다.

java.util.logging

자바에서 기본으로 제공되는 로깅 라이브러리 입니다. 기본적으로 로그 메시지들은 다음과 같이 레벨에 따른 의미를 가지고 있어 로그를 남길때 적절하게 선택해 사용해야 합니다. 로그 레벨은 로깅 프레임워크에 따라 조금씩 다를수 있습니다.

Logger logger = Logger.getLogger("MyLogger");
logger.info("Starting main program");
logger.log(Level.WARNING, "Data file size too big");
logger.finest(throw new Exception());

» 실습: 키보드 입력 및 로깅 종합 실습 예제

실습개요

Scanner 클래스를 이용한 키보드 입력과 자바 기본 로깅 실습예제 입니다.

소스코드

import java.util.Scanner;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ScannerLog {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String name = scan.next();
        int num = scan.nextInt();

        System.out.println(name);
        System.out.println(num);

        Logger logger = Logger.getLogger("MyLogger");
        logger.info("Main program started !!");
        logger.log(Level.WARNING, "Data file size too big");

        logger.setLevel(Level.FINE);
        ConsoleHandler ch = new ConsoleHandler();
        ch.setLevel(Level.FINE);
        logger.addHandler(ch);

        logger.fine("Shutdown main program !!");
    }
}

실행결과

Kim // 키보드 입력
200 // 키보드 입력
Kim
200
6월 09, 2019 11:08:10 오후 javapart1.ScannerLog main
INFO: Main program started !!
6월 09, 2019 11:08:10 오후 javapart1.ScannerLog main
WARNING: Data file size too big
6월 09, 2019 11:08:10 오후 javapart1.ScannerLog main
FINE: Shutdown main program !!

참고 자료