계산의 대상이 되는 것이 피연산자, 계산의 목적이 되는 것이 연산자
package week02;
public class W01 {
public static void main(String[] args) {
int x = 5;
int y = 10;
int z = x + y; // 5(피연산자) +(연산자) 10(피연산자)
System.out.println(z);
}
}
| 산술 연산자 | + - * / % << >> | 사칙 연산과 비트연산 |
| 비교 연산자 | > < >= <= == != | 크고 작음과 같고 다름을 비교: 결과값이 boolean(true, false) |
| 논리 연산자 | && || ! | 그리고(AND)와 또는(OR) 으로 조건을 연결 |
| 대입연산자 | = ++ -- | 우변의 값을 좌변에 저장, 연산 복합 대입 |
| 기타 연산자 | (type) ? : instance of | 형변환 연산자, 삼항 연산자, instance of 연산자 |
🔥 대입 연산자 중에 증감 연산자 쓸 때 주의할 점!
++ 또는 --를 붙이면 피연산자가 1 더해지거나 1 빼기가 된다| 연산자 | 연산자 위치 | 기능 | 연산 예 |
|---|---|---|---|
| ++ | ++{피연산자} | 연산 전에 피연산자에 1 더해줍니다. | val = ++num; (num값+1 후에 val변수에 저장) |
| ++ | {피연산자}++ | 연산 후에 피연산자에 1 더해줍니다. | val = num++; (num값을 val변수에 저장 후 num+1) |
| -- | --{피연산자} | 연산 전에 피연산자에 1 빼줍니다. | val = --num; (num값-1 후에 val변수에 저장) |
| -- | {피연산자}-- | 연산 후에 피연산자에 1 빼줍니다. | val = num--; (num값을 val변수에 저장 후 num-1) |
📌 연산자 우선순위 : 산술 > 비교 > 논리 > 대입
📌 연산 전에 피연산자의 타입을 일치시키는 것
▶︎ if문
// 조건문
boolean flag = true;
if (flag) {
System.out.println("flag 값은 true 입니다."); // flag 값은 true 입니다. 출력
}
▶︎ if-else 문
// 조건문 with else
boolean flag = false;
if (flag) {
System.out.println("flag 값은 true 입니다."); // 미출력
} else {
System.out.println("flag 값은 false 입니다."); // flag 값은 false 입니다. 출력
}
▶︎ if-else if-else문
// 조건문 with else if
int number = 2;
if (number == 1) {
System.out.println("number 값은 1 입니다."); // 미출력
} else if (number == 2) {
System.out.println("number 값은 2 입니다."); // number 값은 2 입니다. 출력
} else {
System.out.println("number 값은 모르는 값입니다."); // 미출력
}
▶︎ 중첩 if 문
// 중첩 조건문
boolean flag = true;
int number = 2;
if (flag) {
if (number == 1) {
System.out.println("flag 값은 true, number 값은 1 입니다."); // 미출력
} else if (number == 2) {
System.out.println("flag 값은 true, number 값은 2 입니다."); // flag 값은 true, number 값은 2 입니다. 출력
}
} else {
if (number == 1) {
System.out.println("flag 값은 false, number 값은 1 입니다."); // 미출력
} else if (number == 2) {
System.out.println("flag 값은 false, number 값은 2 입니다."); // 미출력
}
}
switch 피연산자가 case 조건을 만족하면 case: 뒤에 명시되어 있는 연산을 수행합니다.case(조건): (연산) 은 여러 개를 설정할 수 있습니다.break; 문은 해당 case의 연산문이 끝났다는 것을 알려주어 switch 문을 종료시켜줍니다.❓ 만약 case의 연산문 마지막에
break;를 안 넣어주면 어떻게 될까요?
case의 연산문이 안 끝났기 때문에switch문 블럭이 끝날 때까지 전부 실행됩니다!
▶︎ for 문
for (초기값; 조건문; 증가연산) { (연산) } 형태로 사용합니다.for(int i=0; i < 4; i++) { // 변수 i 값은 0 ~ 3 까지 반복
System.out.println(i + "번째 출력"); // i 변수와 문자열 합치기
}

▶︎ 향상된 for 문
향상된 for 문은 연속된 변수 목록을 출력할 때 쓰입니다.
int[] numbers = {3,6,9,12,15};
for(int number: numbers) {
System.out.print(number + " ");
}

▶︎ while 문
int number = 0;
while(number < 3) {
number++;
System.out.println(number + "출력");
}

▶︎ do-while 문
// do-while 문
int number = 4;
do {
System.out.println(number + "출력");
} while(number < 3); // 연산을 한번 수행 후 조건문 체크
// 조건과 상관 없이 무조건 한 번은 수행

break; 명령을 호출하면 가장 가까운 블럭의 for 문 또는 while 문을 중단합니다. (또는 switch)break; 형태로 사용합니다.int number = 0;
while(number < 3) {
number++;
if (number == 2) {
break; // 2일때 반복 중단
}
System.out.println(number + "출력");
}

✏️ 가장 가까운 블럭의 for 문 또는 while 문을 중단
// break 명령 범위
for (int i = 0; i < 10; i++) {
System.out.println("i: " + i);
if (i == 2) {
break; // i 가 2일때 가장 바깥 반복문이 종료됩니다.
}
for (int j = 0; j < 10; j++) {
System.out.println("j: " + j);
if (j == 2) {
break; // j 가 2일때 가장 안쪽 반복문이 종료됩니다.
}
}
}

// continue 명령
int number = 0;
while(number < 3) {
number++;
if (number == 2) {
continue; // 2일때 반복 패스
}
System.out.println(number + "출력");
}

구구단 생성기 (2단 ~ 9단 출력)
import java.util.Scanner;
public class guguPrinter {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("패스할 단을 입력하세요: ");
int passNum = sc.nextInt();
for(int i=2; i<=9; i++) {
if (i == passNum) {
continue; // 해당 단을 skip
}
for(int j=1; j<=9; j++) {
System.out.println(i + "*" + j + "=" + i*j);
}
}
}
}
📌 Java 프로그래밍에서 여러 개의 변수를 모아서 저장하고 싶을 때 기본적으로는 “배열”이라는 변수에 저장(표현) 합니다.
"분류통"이라고 표현한 이유는 여러 개의 값들을 한꺼번에 넣거나 하나씩 넣을 수도 있고, 꺼낼 때는 하나씩 꺼낼 수 있기 때문입니다.
▶︎ 선언
타입 [] 변수;// 배열 선언
// 일반적인 선언방식
int[] intArray; // 정수 배열
long[] longArray;
double[] doubleArray; // 실수 배열
char[] charArray; // 문자 배열
String[] stringArray; // 문자열 배열
타입 변수[];// 배열 선언
// 2번째 선언방식
int intArray[]; // 정수 배열
long longArray[];
double doubleArray[]; // 실수 배열
char charArray[]; // 문자 배열
String stringArray[]; // 문자열 배열
▶︎ 생성
배열(Array)는 참조형 변수들처럼 new 명령을 통해서 생성하며, 대괄호[] 안에 크기를 지정해 줍니다.

▶︎ 순회
배열에는 순번(index)이 있고 해당 순번을 통해 하나의 값을 조회할 수 있습니다.
배열을 순회하는 방법은 반복문을 사용이 가장 일반적인 방법입니다.
//길이가 3인 정수배열 선언
int[] intArray = new int[3];
// 배열이 초기화된 값을 출력해본다.
for(int i=0; i<intArray.length; i++) { // .length 는 배열의 길이
System.out.println(intArray[i]);
}
▶︎ 초기화
{}를 사용해서 초기화for문을 사용해서 초기화 (또는 향상된 for문)Arrays.fill 메소드를 사용해서 초기화Arrays 클래스는 Java에서 기본으로 제공하는 메소드가 담긴 클래스입니다.import java.util.Arrays;
public class Arr02 {
public static void main(String[] args) {
//1. 배열에 특정값 대입하며 선언
int[] intArray = {1, 2, 3, 4, 5};
String[] stringArray = {"a", "b", "c", "d"};
//2-1. for문을 통해 값을 대입
for (int i = 0; i < intArray.length; i++) {
intArray[i] = i;
}
//2-2. 향상된 for문을 통한 배열 출력
for (int i : intArray) {
System.out.print(i); // 01234
}
System.out.println(); // 줄바꿈
//3. 배열의 주소를 모두 같은값으로 초기화
Arrays.fill(intArray, 1);//배열의 모든 값을 1로 초기화
for (int i : intArray) {
System.out.print(i); // 11111
}
}
}

▶︎ 얕은 복사
배열은 참조형 변수이며 실제 값이 아닌 주소값만 복사되고 실제 값은 1개로 유지되는 걸 얕은 복사라고 한다.
// 얕은 복사
int[] a = { 1, 2, 3, 4 };
int[] b = a; // 얕은 복사
b[0] = 3; // b 배열의 0번째 순번값을 3으로 수정했습니다. (1 -> 3)
System.out.println(a[0]); // 출력 3
▶︎ 깊은 복사
int[] a = { 1, 2, 3, 4 };
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i]; // 깊은 복사
}
b[0] = 3; // b 배열의 0번째 순번값을 3으로 수정했습니다. (1 -> 3)
System.out.println(a[0]); // 출력 1
// 깊은 복사 메서드
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값도 같이 넣어줍니다.
}
}
▶︎ 선언, 생성, 초기화
// String 배열을 아래와 같이 선언과 생성할 수 있습니다.
String[] stringArray = new String[3];
// 선언 후 하나씩 초기화 할 수 있습니다.
stringArray[0] = "val1";
stringArray[1] = "val2";
stringArray[2] = "val3";
// 선언과 동시에 초기화 할 수 있습니다.
String[] stringArray1 = new String[]{"val1", "val2", "val3"};
String[] stringArray2 = {"val1", "val2", "val3"};
▶︎ char[] vs String
👀 [ 기본형 변수 vs 참조형 변수 ]
1. 기본형 변수는 '소문자로 시작', 참조형 변수는 '대문자로 시작'
- Wrapper class 에서 기본형 변수를 감싸줄 때 (boxing) int -> Integer
2. 기본형 변수는 값 자체를 저장, 참조형 변수는 별도의 공간에 값을 저장 후 그 주소를 저장함 (=주소형 변수)
| 메서드 | 응답값 타입 | 설명 |
|---|---|---|
| length() | int | 문자열의 길이를 반환한다. |
| charAt(int index) | char | 문자열에서 해당 index의 문자를 반환한다. |
| substring(int from, int to) | String | 문자열에서 해당 범위(from~to)에 있는 문자열을 반환한다. (to는 범위에 포함되지 않음) |
| equals(String str) | boolean | 문자열의 내용이 같은지 확인한다. 같으면 결과는 true, 다르면 false가 된다. |
| toCharArray() | char[] | 문자열을 문자배열(char[])로 변환해서 반환한다. |
| new String(char[] charArr) | String | 문자배열(char[]) 을 받아서 String으로 복사해서 반환한다. |
package week02.array;
public class Arr05 {
public static void main(String[] args) {
// String 기능 활용하기
String str = "ABCD";
// length()
int strLength = str.length();
System.out.println(strLength); // 4 출력
// charAt(int index)
char strChar = str.charAt(2); // 순번은 0부터 시작하니까 2순번은 3번째 문자를 가리킵니다.
System.out.println(strChar); // C 출력
// substring(int from, int to)
String strSub = str.substring(0, 3); // 0~2순번까지 자르기 합니다. (3순번은 제외)
System.out.println(strSub); // ABC 출력
// equals(String str)
String newStr = "ABCD"; // str 값과 같은 문자열 생성
boolean strEqual = newStr.equals(str);
System.out.println(strEqual); // true 출력
// toCharArray(): String -> char[]
char[] strCharArray = str.toCharArray(); // String 을 char[] 로 변환
// new String(char[]): char[] -> String
char[] charArray = {'A', 'B', 'C'};
String charArrayString = new String(charArray); // char[] 를 String 으로 변환
}
}
▶︎ 2차원 배열
2차원 배열 선언
int[][] arrayint array[][]int[] array[]2차원 배열 생성
2차원 배열 초기화
// 중괄호를 사용해 초기화
int[][] array1 = {
{1, 2, 3},
{4, 5, 6}
};
// 반복문을 통한 초기화
int[][] array2 = new int[2][3]; // 최초 선언
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
array2[i][j] = 0; // i, j 는 위 노란색 네모박스 안에있는 숫자를 의미하며 인덱스 라고 부릅니다.
}
}
▶︎ 가변 배열
2차원 배열을 생성할 때 열의 길이를 생략하여, 행마다 다른 길이의 배열을 요소로 저장
// 가변 배열
// 선언 및 초기화
int[][] array = new int[3][];
// 배열 원소마다 각기다른 크기로 지정 가능합니다.
array[0] = new int[2];
array[1] = new int[4];
array[2] = new int[1];
// 중괄호 초기화할때도 원소배열들의 크기를 각기 다르게 생성 가능합니다.
int[][] array2 = {
{10, 20},
{10, 20, 30, 40},
{10}
};
// 가변 2차원 배열의 조회
for (int i = 0; i < array2.length; i++) { // 1차원 길이
for (int j = 0; j < array2[i].length; j++) { // 2차원 길이
System.out.println("[" + i + "," + j + "]: " + array2[i][j]); // 2중 반복문으로 i, j 인덱스 순회
}
}

▶︎ 3차원 배열
int[][][] multiArrary// 3차원 배열의 이해
// 중괄호 3개를 써서 3차원 배열 초기화를 할 수 있습니다.
int[][][] MultiArray = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
▶ 컬렉션이란?
배열보다 다수의 참조형 데이터를 더 쉽고 효과적으로 처리할 수 있는 기능을 많이 가지고 있습니다.
Collection에는 List, Set , Queue , Map 이 있습니다.List : 순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷Queue : 빨대처럼 한쪽에서 데이터를 넣고 반대쪽에서 데이터를 뺄 수 있는 집합Set : 순서가 없는 데이터의 집합 (데이터 중복 허용 안 함) - 순서 없고 중복 없는 배열Map : 순서가 없는 (Key, Value) 쌍으로 이루어진 데이터의 집합 (Key값 중복 허용 안 함)
순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷

package collection;
import java.util.ArrayList;
public class Col1 {
public static void main(String[] args) {
// List
// 순서가 있는 데이터의 집합 => Array(최초 길이를 알아야 함)
// 처음에 길이를 몰라도 만들 수 있음
// 1) Array -> 정적 배열
// 2) List(ArrayList) -> 동적 배열(크기가 가변적으로 늘어난다)
// - 생성 시점에 작은 연속된 공간을 요청해서 참조형 변수들을 담아놓는다.
// - 값이 추가될 때 더 큰 공간이 필요하면 더 큰 공간을 받아서 저장하니깐, 상관없다.
ArrayList<Integer> intList = new ArrayList<Integer>(); // 선언 + 생성
intList.add(99);
intList.add(15);
intList.add(3);
// System.out.println(intList.get(1));
// 2번째 있는 값(15)를 바꿔보자.
intList.set(1, 10);
// System.out.println(intList.get(1));
// 삭제
System.out.println(intList.get(0));
intList.remove(0);
System.out.println(intList.get(0));
// 리스트 전체 값 삭제
System.out.println("클리어 전");
System.out.println(intList.toString());
intList.clear();
System.out.println("클리어 후");
System.out.println(intList.toString());
}
}


기본적인 기능은 ArrayList 와 동일하지만 LinkedList는 값을 나누어 담기 때문에 모든 값을 조회하는 속도가 느립니다. 대신에, 값을 중간에 추가하거나 삭제할 때는 속도가 빠릅니다.
package collection;
import java.util.LinkedList;
public class Col2 {
public static void main(String[] args) {
// linked list
// 메모리에 남는 공간을 요청해서 여기 저기 나누어서 실제 값을 담는다.
// 실제 값이 있는 주소값으로 목록을 구성하고 저장하는 자료구조
// 기본적 기능은 -> ArrayList 와 동일
// LinkedList는 값을 여기 저기 나누어서 조회하는 속도가 느리다.
// 값을 추가하거나, 삭제할 때는 빠르다.
LinkedList<Integer> linkedList = new LinkedList<Integer>();
linkedList.add(5);
linkedList.add(10);
linkedList.add(3);
System.out.println(linkedList.get(0));
System.out.println(linkedList.get(1));
System.out.println(linkedList.get(2));
System.out.println(linkedList.toString()); // 이렇듯 조회할 때는 arrayList보다 속도가 현저히 느리다.
// 추가
System.out.println("추가: 리스트 마지막에 200 추가");
linkedList.add(200);
System.out.println(linkedList.toString());
System.out.println("추가: [2]에 4 추가 -> 예상 [5, 10, 4, 3, 200]");
linkedList.add(2, 4);
System.out.println(linkedList.toString()); // 특정 위치에 요소를 추가할 수 있다.
// 수정
System.out.println("수정: [1]의 값을 30으로 수정 -> 예상 [5, 30, 4, 3, 200]");
linkedList.set(1, 30);
System.out.println(linkedList.toString());
// 삭제
System.out.println("삭제: [1]의 요소를 삭제 -> 예상 [5, 4, 3, 200]");
linkedList.remove(1);
System.out.println(linkedList.toString());
// 전체 삭제
System.out.println("리스트 전체 삭제");
linkedList.clear();
System.out.println(linkedList.toString());
}
}


Stack 은 값을 수직으로 쌓아놓고 넣었다가 빼서 조회하는 형식으로 데이터를 관리합니다.push, peek, poppackage collection;
import java.util.Stack;
public class Col3 {
// Stack
// 수직으로 값을 쌓아놓고, 넣었다가 뺀다. FILO(Basket)
// push, peek, pop
// 최근 저장된 데이터를 나열하고 싶거나, 데이터의 중복 처리를 막고 싶을 때 사용
public static void main(String[] args) {
Stack<Integer> intStack = new Stack<Integer>(); // 선언 및 생성
intStack.push(10);
intStack.push(15);
intStack.push(1);
// 다 지워질 때 까지 출력
while (!intStack.empty()) {
System.out.println(intStack.pop());
}
// 다시 추가
intStack.push(10);
intStack.push(15);
intStack.push(1);
// peek(): 맨 위(가장 마지막에 추가된 요소)의 값을 조회. 값이 삭제되지는 않는다.
System.out.println(intStack.peek());
// size(): 스택의 전체 크기를 조회
System.out.println(intStack.size());
}
}

Queue은 빨대처럼 한쪽에서 데이터를 넣고 반대쪽에서 데이터를 뺄 수 있는 집합입니다.add, peek, poll💡 Queue는 생성자가 없는 인터페이스
즉, Queue로 객체를 생성할 수 없다.
따라서, Queue를 구현(implements) 하는 하위 클래스인 LinkedList로 객체를 생성한다.
package collection;
import java.util.LinkedList;
import java.util.Queue;
public class Col4 {
// Queue : FIFO
// add(offer), peek, poll
// Queue : 생성자가 없는 인터페이스
public static void main(String[] args) {
Queue<Integer> intQueue = new LinkedList<Integer>(); // Queue 선언, 생성
intQueue.add(1);
intQueue.add(5);
intQueue.add(9);
// 다 지워질때까지 출력
while (!intQueue.isEmpty()) {
System.out.println(intQueue.poll());
}
// 다시 추가
intQueue.add(1);
intQueue.add(5);
intQueue.add(9);
// peek()
System.out.println("peek:" + intQueue.peek()); // 가장 먼저 넣은 요소가 조회됨
// size() : queue의 전체 크기를 조회
System.out.println("size:" + intQueue.size());
}
}


Set 은 순서가 없는 데이터의 집합 (데이터 중복 허용 안 함) : 순서 없고 중복 없는 배열
💡 HashSet : 순서가 보장되지 않음
package collection;
import java.util.HashSet;
import java.util.Set;
public class Col5 {
// Set(집합) : 순서가 없고, 중복이 없음
// 순서가 보장되지 않는 대신 중복을 허용하지 않도록 하는 프로그램에서 사용할 수 있는 자료구조
// Set -> HashSet, TreeSet 등으로 응용해서 같이 사용 가능
// Set은 생성자가 없는 인터페이스라서 바로 생성할 수 없음
// 생성자가 존재하는 HashSet을 이용해서 Set을 구현해 볼 수 있다.
public static void main(String[] args) {
Set<Integer> intSet = new HashSet<Integer>();
intSet.add(1);
intSet.add(12);
intSet.add(5);
intSet.add(9);
intSet.add(1);
intSet.add(12);
for (Integer value : intSet) {
System.out.println(value);
}
// contains(element) : 해당 요소가 set에 포함되어 있는지 여부
System.out.println("contains(2): " + intSet.contains(2));
System.out.println("contains(5): " + intSet.contains(5));
}
}

Map 은 key-value 구조로 구성된 데이터를 저장할 수 있습니다.
💡Key-Value 구조
package collection;
import java.util.HashMap;
import java.util.Map;
public class Col6 {
// Map: Key-value pair 인 점이 중요
// key라는 값으로 unique 하게 보장이 되어야 함
// Map -> HashMap. TreeMap 으로 응용
public static void main(String[] args) {
Map<String, Integer> intMap = new HashMap<>();
// 맵 key-value 추가
intMap.put("일", 11);
intMap.put("이", 12);
intMap.put("삼", 13);
intMap.put("삼", 14);
intMap.put("삼", 15);
// key 값 전체 출력 : 중복된 키는 생략
for(String key : intMap.keySet()) {
System.out.println(key);
}
// value 값 전체 출력
for(int value : intMap.values()) {
System.out.println(value);
} // 가장 마지막에 추가한 값으로 덮어쓰기 되었다!
// key를 가지고 value를 가져오기
System.out.println(intMap.get("삼"));
}
}