쉽게 배우는 자바2[생활코딩] - 공부 기록 |
해당 강의는 https://www.boostcourse.org/cs128 에서 무료로 수강 할 수 있다.
수강 시작 ~ 끝
2023. 05. 30 ~ 2023. 06.05
생활코딩 자바 입문자편 강의인
" 쉽게 배우는 자바2 " 강의 공부 기록.
1. JAVA 제어문
1. 수업소개
학습 목표
제어문이 무엇인지 알아봅니다.
핵심 단어
- 제어문
- boolean data type
- 비교 연산
- 조건문
- 반복문
강의 내용
프로그램이란,
우리가 원하는 작업들을 시간 순서대로 진행하도록 명령하는 것, 하지만 인간의 욕심을 끝이 없고, 작업들을 시간 순서대로 나열하는 것 이상의 작업을 기대하게 됩니다.
진행을 제어하는 조건문과 반복문
- 로그인 기능의 경우, 아이디와 비밀번호가 제대로 맞는지 확인하고, 맞거나 맞지 않다면 어떤 작업을 할지 달라질 수 있습니다.
- 이러한 작업을 위해서는 조건에 따라서 실행할 작업의 순서를 제어하는 조건문이 필요합니다.
- 조건에 따라 다른 작업을 실행하고, 특정 조건을 충족할 때 작업을 반복하기 위해서. 즉, 조건문과 반복문을 위해서는 조건을 구성해야 합니다. 조건을 구성하기 위해서 자바에서는 Boolean 데이터 타입과, 비교 연산 기능을 제공합니다.
2. Boolean Datatype
학습 목표
boolean 데이터 타입에 대해서 알아봅니다.
핵심 단어
- boolean
강의 내용
boolean이라는 데이터 타입에 있는 데이터 두가지
- true
- false
""가 없는 true라는 텍스트는 불리언 이다 라는 약속이 되어 있기때문에 변수의 이름으로 사용 할 수 없다. true, false 처럼 이미 쓰임이 있는 키워드 들은 reserved word 라고 하며 변수로 쓸 수 없다.
public class BooleanApp {
public static void main(String[] args) {
System.out.println("One"); // String
System.out.println(1); // int
System.out.println(true); // 출력되는 true는 불리언 데이터 타입
System.out.println(false); // 출력되는 false는 불리언 데이터 타입
String foo = "Hello world";
//String true = "Hello world"; // ""가 없는 true라는 텍스트는 불리언 이다 라는 약속이 되어 있기때문에 변수의 이름으로 사용 할 수 없다.
System.out.println(foo.contains("world")); // true
// Hello world에는 world가 포함되어 있기때문에 true 출력
System.out.println(foo.contains("egoing")); // flase
}
}
contain은 조건문 반복문과 같이 썼을때 효과적이다. >>해당 문자열이 있는지 라는 조건을 주고 반환값을 가질 수 있기때문이라고 생각한다.
3. 비교연산자(Comparison Operator)
들어가기 전에
지난 시간에 자바에서 참과 거짓을 표현하는 boolean 데이터 타입에 대해서 알아보았습니다.
이번 시간에는 boolean 데이터 타입을 만들어 내는 비교 연산자에 대해서 알아봅니다.
학습 목표
비교 연산자의 종류에 대해 알아봅니다.
핵심 단어
- 비교 연산자
강의 내용
public class ComparisonOperatiorApp {
public static void main(String[] args) {
System.out.println(1 > 1); // false
System.out.println(1 == 1); // true
System.out.println(1 < 1); // false
System.out.println(1 >= 1); // true
// 양쪽의 값을 비교하는 비교 연산자
}
}
비교 연산자 6가지
- a > b : a가 b보다 큼
- a < b : a가 b보다 작음
- a >= b : a가 b보다 크거나 같음
- a <= b : a가 b보다 작거나 같음
- a == b : a가 b와 같음
- a != b : a가 b와 같지 않음
4-1. 조건문 형식
들어가기 전에
이전 시간에 배웠던 boolean 데이터 타입을 이용하여 간단한 조건문을 만들어 봅시다.
학습 목표
boolean 데이터를 조건으로 삼아 조건문을 만들어 봅니다.
핵심 단어
- if문
강의 내용
public class IfApp {
public static void main(String[] args) {
System.out.println("a");
if(true/*불리언만 들어올 수 있음*/) {
System.out.println(1); // ()안에 있는 값이 true면 {}는 실행된다. flase면 실행되지 않는다.
}
System.out.println("a");
if(true) {
System.out.println(1);
} else {
System.out.println(2);
} // true면 1 , 아니면 2
//조건문 속에 조건문
System.out.println("a");
if(false) { /* true가 아니기때문에 else로 넘어감 */
System.out.println(1);
} else {
if(true) {
System.out.println(2); // true 이기 때문에 2가 출력됨
} else {
System.out.println(3);
}
}
//위의 코드를 더 분명하게 작성
System.out.println("a");
if(false) {
System.out.println(1);
} else if(true) {
System.out.println(2);
} else {
System.out.println(3);
}
}
}
if문은 다음 구성 요소로 구성됩니다.
- if
- 조건식
- 코드블럭 (실행할 코드)
- else if
- else
if와 조건식이 필수 구성 요소이고, 나머지는 필수요소가 아닙니다.
조건식에는 boolean 타입만 들어갈 수 있습니다.
if (조건식) {
// code
} else if (조건식) {
} else {
}
4-2. 조건문 응용 1
들어가기 전에
if문의 기본적인 형식, 그 중 조건식을 만들기 위해 boolean 형을 써야 한다
boolean 형을 만들기 위해 키워드로 직접 입력하거나, 비교 연산자,
마지막으로 객체의 메소드를 이용할 수 있습니다.
이번 시간에는 객체의 메소드를 이용해서 if문의 조건식을 만들어 봅니다.
학습 목표
객체의 메소드를 이용해서 조건식을 만듭니다.
핵심 단어
- 메소드
강의 내용
로그인 하는 어플리케이션을 만들어보자
public class AuthApp {
public static void main(String[] args) {
// 먼저 실행시 아규먼트에 egoing를 넣도록 설정했음
System.out.println(args[0]);
String id = "egoing";
String inputId = args[0];
System.out.println("Hi.");
if (inputId == id) {
System.out.println("Master!");
} else {
System.out.println("Who are you?");
} // Master가 출력될거라 예상했지만 who are you가 출력됨. 이유는 아래
/*
==와 같은 비교 연산자는 기본 데이터 형과는 달리 문자열과 같은 객체에는 의도치 않은 결과를 가져올 수 있습니다.
그래서 문자열이 서로 같은지를 비교하기 위해서 String 객체에서는 equals 메소드를 제공하고 있습니다.
*/
if (inputId.equals(id)) {
System.out.println("Master!");
} else {
System.out.println("Who are you?");
} // Master가 출력됨
}
}
inputId.equals(id) 에서 equals 메소드를 통해 boolean 데이터가 리턴됨. ex) ture
boolean을 리턴하는 메소드
객체의 메소드들 중에서도 boolean 값을 리턴하는 것들이 있습니다.
이전 시간에 살펴보았던 String 클래스의 contains 메소드도 그 중 하나입니다.
이번에는 String 클래스의 다른 boolean 리턴 메소드인 equals 메소드를 이용해서
간단한 인증 기능을 구현해 봅니다.
4-3. 조건문 응용 2
들어가기 전에
지난 시간에 만들었던 아이디 인증 프로그램에서 더 나아가서
비밀번호까지 인증할 수 있는 프로그램을 만들어 봅시다.
학습 목표
조건 연산자에 대해서 알아봅니다.
핵심 단어
- 조건 연산자
강의 내용
아이디와 패스워드가 모두 일치해야 하는 로그인 시스템을 만들어보자.
public class AuthApp {
public static void main(String[] args) {
// 먼저 실행시 아규먼트에 egoing를 넣도록 설정했음
System.out.println(args[0]);
String id = "egoing";
String inputId = args[0];
String pass = "1111";
System.out.println("Hi.");
// if (inputId.equals(id)) {
// if(pass.equals(pass)) {
// System.out.println("Master!");
// } else {
// System.out.println("Wrong Password!");
// }
// } else {
// System.out.println("Who are you?");
// }
// 조건 연산자 && 사용해서 한줄로 작성
if (inputId.equals(id) && pass.equals(pass)) {
System.out.println("Master!");
} else {
System.out.println("Who are you?");
}
}
}
tip) 이클립스에서 범위 주석은 Ctl + /
조건 연산자는 &&(AND)와 ||(OR, shift + \)가 있습니다.
위와 같이 아이디와 패스워드가 모두 같은지 확인하기 위해서는 AND 연산자를 사용합니다.
&& 연산자는 전항과 후항이 모두 참일 경우에만 참을 반환하고, 아니면 거짓을 반환합니다.
|| 연산자는 전항과 후항 중 하나라도 참일 경우에 참을 반환하고, 모두 거짓일 때에만 거짓을 반환합니다.
사칙연산과 같이 && 연산자는 || 연산자보다 우선순위가 높습니다.
5. == vs equals
들어가기 전에
문자열에는 == 연산자 대신 equals 메소드를 이용했습니다.
== 연산자를 이용할 경우에 같은 문자열처럼 보이는데도 false를 반환했는데,
왜 == 연산자는 의도하는 대로 연산하지 못할까요? 이에 대해서 알아봅니다.
학습 목표
== 연산자와 equals 메소드의 차이점에 대해서 알아봅니다.
핵심 단어
- equals 메소드
- 변수와 메모리
강의 내용
데이터 타입을 원시 / 비원시로 나눌수 있음 ( primitive / non primitve )
원시 데이터타입 : boolean, byte, char, short, int, long, float, double
원시 데이터 타입의 변수는 선언되면 메모리(Stack)에 공간이 할당되며,
그 메모리 공간 안에 실제 값이 들어가게 됩니다.
그래서 원시 데이터의 경우 == 연산자는 변수가 가리키는 값을 토대로 비교하게 됩니다.
반면 java.lang.Object 클래스를 비롯해 여기에서 파생된 다른 모든 클래스들은 원시 데이터 타입이 아닙니다.
클래스는 new 키워드를 통한 인스턴스가 만들어지는 시점에
또다른 메모리 구역(Heap)에서 새로운 공간을 할당하여 값을 저장하고 변수는 그 값이 저장된 메모리의 주소를 가리키게 됩니다.
그래서 인스턴스 간 == 연산자를 이용할 경우 그 메모리의 주소를 비교하게 됩니다.
한편 문자열 리터럴과 같은 방식으로 문자열을 생성한 경우는 위와 같은 방식과는 조금 다릅니다.
문자열 리터럴(아래의 s3, s4의 경우)로 문자열을 생성할 때, 이미 같은 문자열을 생성한 적이 있다면(s4의 경우)
새로 메모리 공간을 할당하지 않고,
새로운 변수는 기존의 문자열이 저장된 메모리(String Pool(Heap))의 주소를 가리키게 됩니다.
그래서 이러한 경우에는 == 연산자를 이용하였을 때
같은 주소를 가리키고 있기 때문에 true가 나오게 됩니다.
원시데이터는 메모리(Stack)에 할당.
원시데이터가 아니면 다른곳에 할당. ex) Heap, String Pool(Heap)
int p1 = 1
int p2 = 1
p1도 stack에 1을 저장하고, p2도 stack의 다른 주소에 1을 저장.
“==” 연산자는 stack에 있는 1 과 1을 비교해서 같다고 판단.
String o1 = new String(”java”)
String o2 = new String(”java”)
- new 사용해서 인스턴스가 만들어지고
- 메모리 heap의 새로운 공간에 “java” 문자열 값이 들어간다.
- 메모리 공간에는 주소라는 개념이 있다.
- 따라서, Heap 메모리에 특정 주소에는 “java” 값이 존재한다.
- java라는 값이 존재하는 Heap 메모리의 주소값은 Stack 메모리의 새로운 공간에 저장된다
- 따라서, Stack 메모리의 특정 주소에는 “java” 값이 존재하는 heap 메모리의 주소값이 저장된다.
- o1은 “java” 값이 존재하는 Heap 메모리의 주소값을 저장하는 Stack 메모리를 가리킨다.
o2도 동일한데, 다만 heap공간에 이미 “java”가 있지만 새로운 공간에 “java” 값을 저장한다.
따라서 Heap 공간의 주소값이 다르고. 이 주소값은 Stack의 새로운 공간에 저장된다.
o2는 “java” 값이 존재하는 새로운 Heap 메모리의 주소값을 저장하는 새로운 Stack 메모리를 가리킨다.
따라서 o1 == o2 연산을 실행하면 o1이 가리키는 stack 메모리에 있는 heap 메모리 주소값 과 o2가 가리키는 stack 메모리에 있는 heal 메모리의 주소값이 다르다. false를 반환
여기서 equals 메소드를 사용하면
ex) o1.equals(o2)
o1, o2라는 변수가 최종적으로 가리키고 있는 값을 기준으로 판단하기 때문에 “java”와 “java”는 저장된 공간이 다르지만 값이 같다고 true를 반환한다.
String o3 = “java2”
String o4 = “java2”
// o1 과 o2 의 1은 데이터와 데이터가 저장된 메모리의 위치도 같다.
위 방식은 문자열 리터럴과 같은 방식으로 문자열을 생성한 경우이며, 이때
o3에서 “java2” 문자열 값을 heap 공간에 생성하고,
o4에서는 기존에 heap 공간에 생성된 “java2”문자열을 사용한다.
따라서, o3와 o4가 가리키는 stack메모리에는 “java2” 값이 저장된 동일한 heap 메모리의 주소값이 들어있다. 그래서 o3 == o4 는 true 반환
참고. 이해를 돕기위한 이미지로 실제 작동과 다를 수 있음.
int a = 1;
int b = 1;
String s1 = new String("JAVA");
String s2 = new String("JAVA");
String s3 = "JAVA";
String s4 = "JAVA";
객체변수 = 인스턴스 변수
##왜 객체 변수는 실제 값이 아니라 값이 저장된 또다른 메모리 공간의 주소를 가리키는지 확인해볼것
6. 논리연산자
들어가기 전에
지금까지 배운 내용들을 종합하여 인증 프로그램을 더 멋지게 만들어 봅시다.
학습 목표
논리 연산자(조건 연산자)를 모두 파악하고 적절하게 활용한다.
핵심 단어
- 논리 연산자
교육 내용
public class LogicalOperatorApp {
public static void main(String[] args) {
// AND 연산자 &&
System.out.println(1 == 1); // true
System.out.println(true && true); // true
System.out.println(true && false); // false
System.out.println(false && true); // false
System.out.println(false && false); // false
// OR 연산자 ||
System.out.println(true || true); // true
System.out.println(true || false); // true
System.out.println(false || true); // true
System.out.println(false || false); // false
// not
System.out.println( !true); // false
System.out.println( !false); // true
}
}
만들엇던 로그인 프로그램에 비밀번호를 두개 만들고 둘중 하나만 맞더라도 로그인 되도록
public class AuthApp2 {
public static void main(String[] args) {
// 먼저 실행시 아규먼트에 egoing를 넣도록 설정했음
System.out.println(args[0]);
String id = "egoing";
String inputId = args[0];
String pass = "1111";
String pass2 = "2222";
System.out.println("Hi.");
boolean isRightPass = ( pass.equals(pass) || pass.equals(pass2) );
if (inputId.equals(id) && isRightPass ) {
System.out.println("Master!");
} else {
System.out.println("Who are you?");
}
}
}
7-1. 반복문
들어가기 전에
우리는 조건에 따라 특정한 작업을 하도록 if문을 이용해 보았습니다.
조건에 따라 특정한 작업을 반복하게 하려면 어떻게 해야할까요?
이번 시간에는 반복문의 형식에 대해서 알아봅니다.
학습 목표
while문과 for문의 형식을 알아봅니다.
핵심 단어
- 반복문
- while문
- for문
학습 내용
public class LoopApp {
public static void main(String[] args) {
System.out.println(1);
System.out.println("===== while =====");
int i = 0;
while(i < 3) {
System.out.println(2);
System.out.println(3);
// i = i + 1 ;
i++;
}
System.out.println("===== for =====");
for(int j = 0; j <3; j++) {
System.out.println(2);
System.out.println(3);
}
System.out.println(4);
}
}
while문 보다 for 문이 코드가 길어지더라도 이해하기 쉽다.
7-2. 배열
들어가기 전에
반복문과 같이 사용할때 사용하기 좋은 데이터 타입이 있습니다.
배열은 같은 데이터를 여러 개 묶어놓은 형태로, 반복되는 작업을 수행할 때 유용하게 사용할 수 있습니다.
이번 시간에는 배열에 대해서 알아봅니다.
학습 목표
배열의 구조에 대해서 알아봅니다.
핵심 단어
- 배열
강의 내용
배열
배열은 같은 데이터 타입을 여러 개 묶어놓은 형태의 데이터입니다.
배열을 선언할 때는 변수 타입명 뒤에 빈 [ ] 대괄호를 입력하고 변수 이름을 입력합니다.
초기화를 할 경우에는 new 키워드를 이용하여 [ ] 대괄호 안에 요소의 개수를 입력합니다.
또는 리터럴로 입력할 수 있는 데이터 타입의 경우, { } 중괄호 안에 요소를 리터럴로 입력할 수 있습니다.
배열은 인덱스를 통해 접근하고 인덱스는 [ ] 대괄호 안에 입력합니다.
public class ArrayApp {
public static void main(String[] args) {
// 사용자의 명단을 보관, 관리 해야 하는 상황
// String users = "egoing, jinhuck, youbin";
String[] users = new String[3];
users[0] = "egoing";
users[1] = "jinhuck";
users[2] = "youbin";
System.out.println(users[1]);
System.out.println(users.length); // 3 // 3칸짜리 배열이다.
int[] scores = {10, 100, 100};
System.out.println(scores[1]);
System.out.println(scores.length); // 3
// 0 ,1 ,2 와같은 자리수는 Index ... 원하는 값을 찾기위한 색인이다 라는 의미
// "egoing" , "jinhyuck", "youbin" // 배열을 이루고있는 원소(Element)
}
}
7-3. 반복문 + 배열
들어가기 전에
지난 시간에 반복문과 배열에 대해서 알아 보았습니다.
반복문은 배열과 함께 쓰면 유용성이 크게 늘어날 수 있습니다.
이번 시간에는 배열의 요소를 반복문을 이용해서 처리하는 방법에 대해서 알아봅니다.
학습 목표
반복문을 통해 배열의 요소들에 대해 같은 작업을 수행해 봅니다.
핵심 단어
- 반복문
- 배열
- length 필드
강의 내용
public class LoopArray {
public static void main(String[] args) {
/*
* 각각의 사람 이름 앞뒤로 <li> 라는 html 태그를 만들어 볼것임
* 결과는 아래처럼 된다.
*/
/*
* <li>egoing</li>
* <li>jinhuck</li>
* <li>youbin</li>
*/
String[] users = new String[3];
users[0] = "egoing";
users[1] = "jinhuck";
users[2] = "youbin";
for(int i = 0; i < users.length; i++ ) {
System.out.println("<li>"+users[i]+"</li>");
}
}
}
users.length 에서 length 필드를 통해 users 배열의 요소 개수를 알 수 있다.
8-1. 종합응용 1
들어가기 전에
지금까지 배운 내용을 종합하여 응용해 봅니다.
로그인 기능을 좀 더 유용하게 만들어 봅니다.
학습 목표
배열과 반복문을 이용해서 이전에 했던 로그인 프로그램을 좀 더 확장해 봅니다.
핵심 단어
- 배열
- 반복문
강의 내용
이번에는 이전에 만들었던 로그인 기능을 좀 더 확장해서,
여러 아이디를 인증할 수 있는 기능을 추가해 봅니다.
public class AuthApp3 {
public static void main(String[] args) {
String[] users = {"egoing", "jinhuck", "youbin"};
String inputId = args[0]; // inputId에 아규먼트를 입력받음
// 입력받은 값이 users에 있는지 체크하는 코드
boolean isLogined = false; // 로그인 되어있는지 상태를 알려고
for(int i = 0; i < users.length; i++) {
String currentID = users[i];
if(currentID.equals(inputId)) {
isLogined = true;
break;
}
}
System.out.println("hi");
if(isLogined) {
System.out.println("Master");
} else {
System.out.println("wtf?");
}
}
}
break 문은 더 이상 현재 반복문을 진행하지 않고 빠져나오게 하는 구문입니다.
배열에 요소들이 더 남아 있다고 할지라도 break 문을 만나면 더 이상 추가적인 연산을 수행하지 않고 현재 반복문의 코드블럭 밖으로 빠져나옵니다.
8-2. 종합응용 2
들어가기 전에
지난 번에 만들었던 로그인 기능에서 비밀번호도 추가해서 함께 비교해 봅니다.
학습 목표
이차원 배열을 만들어서 반복문을 구현합니다.
핵심 단어
- 이차원 배열
강의 내용
위에 로그인 프로그램에 비밀번호 관리하는것 까지,
이차원 배열을 구성하여 아이디와 비밀번호를 모두 저장하는 방식으로
로그인 기능을 구현해 봅니다.
public class AuthApp3 {
public static void main(String[] args) {
//String[] users = {"egoing", "jinhuck", "youbin"};
String [] [] users = {
{"egoing", "1111"},
{"jinhuck", "2222"},
{"youbin", "3333"}
};
String inputId = args[0]; // inputId에 아규먼트를 입력받음
String inputPass = args[1];
boolean isLogined = false;
for(int i = 0; i < users.length; i++) {
String [] currentID = users[i];
if(
currentID[0].equals(inputId) &&
currentID[1].equals(inputPass)
) {
isLogined = true;
break;
}
}
System.out.println("hi");
if(isLogined) {
System.out.println("Master");
} else {
System.out.println("wtf?");
}
}
}
이차원 배열은 다음과 같은 모양을 가지고 있습니다.
인덱스를 이용하여 접근할 경우 행, 열의 순서로 접근합니다.
따라서 "egoing" 문자열은 users[0][0]이고,
"3333" 문자열은 users[2][1]로 접근합니다.
또한 users[0]은 String 객체가 아닌 String[] 객체, 즉 일차원 배열입니다.
'들은 강의' 카테고리의 다른 글
[생활코딩 자바2] - 3. JAVA 객체지향 프로그래밍(클래스, 인스턴스, static, this) (0) | 2023.06.06 |
---|---|
[생활코딩 자바2] - 2. JAVA 메소드(리팩토링, 파라미터, return) (1) | 2023.06.06 |
[생활코딩 자바1] - 4. 나의 앱 만들기 (0) | 2023.06.06 |
[생활코딩 자바1] - 3. Java 프로그래밍 시작하기 (0) | 2023.06.06 |
[생활코딩 자바1] - 2. JAVA 프로그래밍 구성 (0) | 2023.06.06 |