티스토리 뷰
1. 배열 개요
→ 나중에는 컬렉션을 사용!!
1-1. 배열 정의 및 사용 이유
1-1-1. 배열이란?
💡동일한 자료형(Data Type)의 묶음(→이 묶음을 인지시킨다.)
연속된 메모리(주기억장치, RAM) 공간에 값을 저장하고 사용하기 위한 용도로 사용
배열은 heap 영역에 new 연산자를 통해 할당
배열의 길이는 최초 선언한 값으로 "고정", 인덱스를 통해 데이터에 접근 가능
1-1-2. 배열을 사용하는 이유
- 배열을 사용하지 X → 동일한 자료형을 가진 다양한 값들을 각각의 변수에 저장하여 사용
(모든 변수의 이름을 사용자가 관리) - 연관된 데이터를 저장하기 위한 변수의 선언을 줄여주며, 반복문 등을 이용하여 계산과 같은 과정을 쉽게 처리
package com.ohgiraffers.section01.array;
import java.util.Arrays;
public class Application1 {
public static void main(String[] args) {
/* 수업목표. 배열에 대해 이해하고 배열의 사용 목적을 이해할 수 있다. */
int num1 = 10;
int num2 = 20;
int num3 = 30;
int num4 = 40;
int num5 = 50;
int sum = 0;
sum += num1;
sum += num2;
sum += num3;
sum += num4;
sum += num5;
System.out.println("sum = " + sum);
int[] arr = new int[5]; // 초기상태 : [0][0][0][0][0]
System.out.println(Arrays.toString(arr));
// arr[0] = 10;
// arr[1] = 20;
// arr[2] = 30;
// arr[3] = 40;
// arr[4] = 50;
/* 설명. 반복문을 활용한 배열 초기화 */
for (int i = 0; i < 5; i++) {
arr[i] = (i +1) *10;
}
/* 설명. 반복문을 활용해 초기화 된 값 확인 */
for (int i = 0; i < 5; i++) {
System.out.println(arr[i]);
}
/* 설명. 앞서 확인한 값들을 각각 sum에 누적 */
for (int i = 0; i < 5; i++) {
sum += arr[i];
}
System.out.println("sum = " + sum);
/* 설명. 1차원 배열을 쉽게 확인하는 방법 */
System.out.println(Arrays.toString(arr)); // 배열 안에 있는 값을 출력.
}
}
// 실행 결과
sum = 150
[0, 0, 0, 0, 0]
10
20
30
40
50
sum = 300
[10, 20, 30, 40, 50]
2. 배열
2-1. 1차원 배열 개요
2-1-1. 1차원 배열 선언
- 배열을 선언할 때 방법
- 참조 변수만 먼저 선언하여 크기 및 값을 이후에 초기화
- 최초 선언 시 배열의 크기 및 값을 할당
💡 int[] arr = new int[5] 설명
- int[] 는 참조 자료형!! 참조자료형은 4 byte
- new 는 heap 영역으로!!
- heap 영역은 기본값으로 채워진다. heap은 비어있지 않다.
- Stack에는 주소가 저장된다. heap 영역 어딘가에 있어!!
package com.ohgiraffers.section01.array;
public class Application2 {
public static void main(String[] args) {
/* 수업목표. 배열의 사용 방법을 익혀 배열을 사용할 수 있다. */
/* 필기.
* 배열의 사용 방법
* 1. 배열의 선언
* 2. 배열의 크기 할당
* 3. 배열의 인덱스 공간에 값 대입
*/
int[] iArr;
// char cArr[]; // 대괄호가 뒤에 붙어도 돌아가지만 권장되진 X
// iArr = new int[]; // 배열은 반드시 크기를 할당해 주어야 한다.
iArr = new int[10]; // 인스턴스화
char[] cArr = new char[5]; // 선언과 크기 할당 한번에 가능
/* 설명. 참조자료형 변수 출력 결과 = toString()의 결과 -> 자료형@16진수 주소값 */
/* 필기. 기본 자료형이 아닌 것을 출력하면 .toString이 붙은 것을 출력하는 것이다. */
System.out.println("iArr = " + iArr.toString()); // 실제로 .toString이 붙은 것!
System.out.println("cArr = " + cArr);
System.out.println("iArr의 10진수 주소: " + iArr.hashCode());
System.out.println("cArr의 10진수 주소: " + cArr.hashCode());
cArr = null;
System.out.println("null을 참조할 시: " + cArr.hashCode()); // .앞에 null이 있으면 볼 수 없다.
// NullPointerException : 무엇도 가르킬 것이 없다.
// 가르키는 것이 없으면 heap 에서 낙동강 오리알 신세인 것이 GC(가비지 콜렉터)가 old 영역으로 옮긴다.
// GC(가비지 콜렉터) -> 면접 많이 나온다!
}
}
// 실행 결과
// iArr = [I@7344699f
// cArr = [C@7e9e5f8a
// iArr의 10진수 주소: 1933863327
// cArr의 10진수 주소: 2124308362
package com.ohgiraffers.section01.array;
import java.util.Arrays;
public class Application3 {
public static void main(String[] args) {
/* 수업목표. 배열에 초기화 되는 자료형별 기본값을 이해할 수 있다. */
/* 필기.
* 값의 형태별 기본값
* 정수: 0
* 실수: 0.0
* 논리: false
* 문자: \u0000
* 참조: null
* */
int[] iArr = new int[5];
System.out.println(Arrays.toString(iArr));
boolean[] bArr = new boolean[6];
System.out.println(Arrays.toString(bArr));
/* 설명. 크기 할당 및 초기화를 한번에 하고 싶을 때 */
int[] iArr2 = {10, 11, 12, 13, 14}; // 안될때가 있다. 이해 안됨!
int[] iArr3 = new int[]{10, 11, 12, 13, 14}; // 이건 무조건 된다.
/* 설명. new int[]을 빼고 배열 생성이 안되는 경우 */
// test({10, 11, 12, 13, 14}); // 오류 발생!!!
// test(new int[]{10, 11, 12, 13, 14});
/* 설명. 배열의 각 요소를 확인하는 세 가지 방법 */
String[] sArr = {"apple", "banana", "grape", "orange"};
/* 설명. 1. 단순 for문 사용 */
for (int i = 0; i < sArr.length; i++) { // .length는 배열의 길이(크기)
System.out.println(sArr[i]);
}
/* 설명. 2. Arrays.toString() 사용 */
System.out.println(Arrays.toString(sArr));
/* 설명. 3. for-each문 사용(향상된 for문) */ // 처음부터 끝까지 돌릴 때 사용!
for (String str: sArr) { // 왼쪽 : 요소 하나씩 담을 수 있는 변수 / 오른쪽 : 반복할 배열
System.out.println(str);
}
}
public static void test(int[] arr) { // 배열을 받는 것이 아니라 배열의 주소값을 받는다. 반환값이 참조자료형일 때...
}
}
/* 실행 결과
[0, 0, 0, 0, 0]
[false, false, false, false, false, false]
apple
banana
grape
orange
[apple, banana, grape, orange]
apple
banana
grape
orange
*/
package com.ohgiraffers.section01.array;
import java.util.Arrays;
import java.util.Scanner;
public class Application4 {
public static void main(String[] args) {
/* 수업목표. 배열을 사용하는 예시를 이해하고 적용할 수 있다. */ // 배열 사용? 반복문 쓰겠구나!!
/* 설명. 5명의 자바 점수를 입력 받아서 합계와 평균을 실수(double)로 구하는 예제 작성 */
int[] score = new int[5];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < score.length; i++) {
System.out.print((i + 1) + "번째 학생의 자바 점수를 입력해 주세요: ");
score[i] = sc.nextInt();
}
System.out.println("현재까지 입력된 값: " + Arrays.toString(score)); // 중간중간 실행하면서 확인하자(검산)
/* 설명. 합계(sum) 구하기 */
int sum = 0;
for (int perScore: score) {
sum += perScore;
}
System.out.println("합계: " + sum);
/* 설명. 평균(avg) 구하기 */
double avg = sum / score.length;
System.out.println("평균: " + avg);
}
}
package com.ohgiraffers.section01.array;
public class Application5 {
public static void main(String[] args) {
/* 수업목표. 배열을 사용하는 예시를 통해 카드 게임을 작성해 보자. */
String[] shape = {"SPADE", "CLOVER", "HEART", "DIAMOND"};
String[] cardNumber = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "JACK", "QUEEN", "KING", "ACE"};
int randomShapeIndex = (int) (Math.random() * shape.length); // 0 ~ 3
int randomCardNumberIndex = (int) (Math.random() * cardNumber.length); // 0 ~ 12
System.out.println("당신이 뽑은 카드는 " + shape[randomShapeIndex] + " " + cardNumber[randomCardNumberIndex] + "카드 입니다.");
}
}
2-2. 다차원 배열 개요
2-2-1. 2차원 배열 선언
- 일부 인덱스는 또 다른 배열의 주소를 보관하는 배열 역할
즉, 2차원 배열은 1차원 배열 여러 개를 하나로 묶어서 관리하는 배열 - 1차원 배열을 관리하는 또 다른 1차원 배열!
package com.ohgiraffers.section02.dimensional;
import java.util.Arrays;
public class Application1 {
public static void main(String[] args) {
/* 수업목표. 다차원 배열의 구조를 이해하고 사용할 수 있다. */
/* 필기.
* 다차원 배열
* 다차원 배열은 2차원 이상의 배열을 의미한다.
* (일반적으로는 사람의 인지 범위에 맞게 최대 3차원 정도를 고려한다.
* */
int[][] iArr1;
int[] iArr2[]; // 추천 X
int iArr3[][]; // 추천 X
iArr1 = new int[3][2]; // 정변 배열을 위한 선언(관리하는 1차원 배열의 길이가 동일)
iArr2 = new int[3][]; // 가변 배열을 위한 선언(관리하는 1차원 배열의 길이가 다를 시)
// iArr3 = new int[][]; // 컴파일 에러 발생
int num = 0;
for (int i = 0; i < iArr1.length; i++) { // 1차원 배열을 고르는 for문
System.out.println("iArr1[i] = " + iArr1[i]); // 관리하는 1차원 배열 주소값
for (int j = 0; j < iArr1[i].length; j++) { // 선택된 1차원 배열을 다루는 for문
iArr1[i][j] = num++;
}
System.out.println(Arrays.toString(iArr1[i]));
}
/* 설명. Arrays.toString()은 1차원 배열만 확인 가능하다. */
System.out.println("2차원 배열도 한번에 확인 될까? " + Arrays.toString(iArr1));
/* 설명. 가변배열에 다양한 길이의 1차원 배열을 적용해 보자. */
iArr2[0] = new int[]{1, 2, 3};
iArr2[1] = new int[]{1, 2, 3, 4};
iArr2[2] = new int[]{3, 3};
for (int i = 0; i < iArr2.length; i++) {
System.out.println(Arrays.toString(iArr2[i]));
}
}
}
// 실행 결과
iArr1[i] = [I@6b95977
[0, 1]
iArr1[i] = [I@7e9e5f8a
[2, 3]
iArr1[i] = [I@8bcc55f
[4, 5]
2차원 배열도 한번에 확인 될까? [[I@6b95977, [I@7e9e5f8a, [I@8bcc55f]
[1, 2, 3]
[1, 2, 3, 4]
[3, 3]
3. 배열의 복사
3-1. 배열의 복사 개요
3-1-1. 배열의 복사란?
💡 자바에서는 배열은 목적에 따라 복사를 해야 할 경우가 있다.
3-1-2. 복사의 종류
💡 배열의 2가지 복사
1. 얕은 복사(shallow copy) : stack 의 주소값만 복사, 원본을 공유할 목적
2. 깊은 복사(deep copy) : heap의 배열에 저장된 값을 복사, 원본과 사본을 분리하여 관리 할 목적 → 원본에 영향 가지 않는다.
3-2. 얕은 복사 개요
3-2-1. 얕은 복사란?
package com.ohgiraffers.section03.copy;
import java.util.Arrays;
public class Application1 {
public static void main(String[] args) {
/* 수업목표. 배열의 복사 개념 중 얕은 복사에 대해 이해할 수 있다. */
/* 필기.
* 배열의 복사에는 크게 두 가지 개념이 있다.
* 1. 얕은 복사(shallow copy): stack의 주소 값만 복사
* 2. 깊은 복사(deep copy): heap의 배열에 저장된 값을 복사
* */
int[] originArr = {1, 2, 3};
int[] copyArr = originArr; // 참조 주소 값 복사(얕은 복사) / 활용하는 걸 이해하자!!
System.out.println(Arrays.toString(copyArr));
copyArr[2] = 100;
System.out.println(Arrays.toString(originArr));
test(originArr); // 이렇게 해도 얕은 복사가 일어난다.
// int[] arr = originArr;
}
public static void test(int[] arr) {
}
}
// 실행 결과
[1, 2, 3]
[1, 2, 100]
3-3. 깊은 복사 개요
3-3-1. 깊은 복사란?
package com.ohgiraffers.section03.copy;
import java.util.Arrays;
public class Application2 {
public static void main(String[] args) {
/* 수업목표. 깊은 복사에 대해 이해할 수 있다. */
/* 필기.
* 깊은 복사를 하는 방법은 4가지가 있다.
* 1. for문을 이용한 동일한 인덱스 값을 일일이 복사
* 2. Object의 clone()을 이용한 복사(사용 빈도 높음)
* 3. System의 arraycopy()를 이용한 복사
* 4. Arrays의 copyOf()를 이용한 복사
* */
int[] originArr = new int[]{1, 2, 3, 4};
print(originArr, "원본");
/* 목차. 1. for문 활용 */
int[] copyArr1 = new int[originArr.length];
for (int i = 0; i < copyArr1.length; i++) {
copyArr1[i] = originArr[i];
}
print(copyArr1, "for문을 활용한 사본"); // print 어떻게 사용?? print 클래스!!
/* 목차. 2. clone() 활용 */
int[] copyArr2 = originArr.clone();
print(copyArr2, "clone()을 활용한 사본");
/* 목차. 3. arraycopy()를 이용한 복사 */
int[] copyArr3 = new int[originArr.length + 3]; // 원본보다 3 크기가 더 큰 배열 할당
System.arraycopy(originArr, 0, copyArr3, 3, 3);
print(copyArr3, "arraycopy()를 활용한 사본");
/* 목차. 4. copyOf()를 이용한 복사(원본의 처음부터만 가능) */
int[] copyArr4 = Arrays.copyOf(originArr, 2);
print(copyArr4, "copyOf()를 활용한 사본");
}
public static void print(int[] arr, String desc) { // 출력 편하게 하기 위해
System.out.println("=======" + desc + "=======");
System.out.println("넘어온 배열의 hashCode: " + arr.hashCode());
System.out.println(Arrays.toString(arr));
}
}
// 실행 결과
=======원본=======
넘어온 배열의 hashCode: 205029188
[1, 2, 3, 4]
=======for문을 활용한 사본=======
넘어온 배열의 hashCode: 2018699554
[1, 2, 3, 4]
=======clone()을 활용한 사본=======
넘어온 배열의 hashCode: 1311053135
[1, 2, 3, 4]
=======arraycopy()를 활용한 사본=======
넘어온 배열의 hashCode: 118352462
[0, 0, 0, 1, 2, 3, 0]
=======copyOf()를 활용한 사본=======
넘어온 배열의 hashCode: 1550089733
[1, 2]
'한화시스템 > 백엔드' 카테고리의 다른 글
[BE] JAVA_클래스와 객체_캡슐화 (0) | 2024.07.16 |
---|---|
[BE] JAVA_클래스와 객체 (0) | 2024.07.15 |
[BE] JAVA_분기문 (0) | 2024.07.13 |
[BE] JAVA_반복문 (0) | 2024.07.13 |
[BE] JAVA_조건문 (0) | 2024.07.13 |