JAVA_04_배열

송지윤·2024년 2월 6일

Java

목록 보기
8/22

배열(Array)

같은 자료형의 변수를 하나의 묶음으로 다루는 것
묶여진 변수들은 하나의 배열명으로 불러지고 구분은 index를 이용
(배열은 저장된 값마다 인덱스 번호가 0부터 시작하여 설정)

javaScript 배열의 특징

  1. 길이 제한 X
  2. 자료형 구분 X

java 배열의 특징

  1. 한 가지 자료형만 저장 가능하다.
  2. 여러 값을 저장할 수 있다.
  3. 한 번 크기를 지정하면 변경 불가능하다.

용어정리

  • 변수 : 메모리에 값을 저장할 수 있는 공간
  • 변수 선언 : 메모리에 값을 저장할 수 있는 공간을 할당

변수 선언

int num;
stack 영역에 int 자료형을 저장할 수 있는 공간 4byte 를 할당하고 그 공간에 num 이라는 이름을 부여.

변수 대입

num = 10;
생성된 num 이라는 변수 공간에 10 이라는 값을 대입

변수 사용

System.out.println("num에 저장된 값 : " + num);
num 이 작성된 자리에 num 에 저장된 값을 읽어와서 출력

배열 선언과 할당

(변수와는 의미가 조금 다름)

배열 선언

메모리에 배열을 참조하는 변수 공간을 만드는 것
(값 직접 저장 X, 배열의 주소를 저장)

자료형[] 배열명;
int[] arr;

자료형 배열명[];
int arr[]

Stack 영역에 int[] 자료형 공간을 4byte 할당하고 그 공간에 arr, str 이라는 이름을 부여
해당 변수는 참조형으로 주소값만을 저장할 수 있다.

배열 할당

실제 값을 저장할 수 있는 배열을 메모리에 생성

앞부분이 배열 선언 뒷 부분이 배열 할당
자료형[] 배열명 = new 자료형[배열크기];
자료형 배열명[] = new 자료형[배열크기];

ex) int[] arr = new int[3];
int arr[] = new int[3];

new : "new 연산자" 라고 하며 Heap 메모리 영역에 새로운 공간(배열, 객체)을 할당

int[3] : int 자료형 변수 3개를 하나의 묶음으로 나타내는 배열

new int[3] : heap 영역에 int 3칸 짜리 int[] 을 생성(할당)
생성된 int[]에는 시작 주소가 지정

arr = new int[3];
(int[]) (int[]) => 같은 자료형 == 연산 가능

arr = new double[5];
arr 은 int 형
자료형이 다르면 연산이 안됨

heap 영역에 생성된 int[]의 시작주소를 stack 영역에 생성된 arr 변수에 대입
-> arr 변수가 int[]을 참조하게됨
그래서 arr 을 참조형이라고 함.

배열 저장구조

배열은 참조 변수로 Heap영역에 할당되며 배열 공간의 주소를 저장
배열 공간의 주소를 이용해 인덱스를 참조하는 방식으로 값 처리

JVM RAM 구조

Heap 영역에 할당된 공간은 절대 비어있을 수 없다.
-> 최초 할당 시 JVM 기본값이 자동 저장된다. (컴파일러)
(boolean은 false, 나머지는 0, 참조형 null)

배열 초기화

인덱스를 이용한 초기화

ex)
arr[0] = 1;
arr[1] = 2;

for문을 이용한 초기화

index가 순차적으로 증가함에 따라 초기화할 리터럴 값이 규칙적이라면 반복문을 통해 배열 초기화 가능

ex)
for(int i = 0; i < arr.length; i++) {
arr[i] = i;
}

선언과 동시에 초기화

ex)
int[] arr = {1, 2, 3, 4, 5};
int[] arr = new int[] {1, 2, 3, 4, 5};
String fruit[] = {"사과", "포도", "참외"};

사용 예

public void ex5() {
	
	char[] arr = new char[5];
	
	for(int i = 0 ; i < arr.length; i++) {
		arr[i] = (char)('A' + i);
	}
	
	System.out.println(Arrays.toString(arr)); // [A, B, C, D, E]
	
	int[] arr2 = new int[4]; // [0,0,0,0]
	System.out.println(Arrays.toString(arr2)); // [0, 0, 0, 0]
	// int형 배열 4칸짜리 생성 후 각 인덱스에 값을 대입하지 않았으므로
	// JVM에 의해 int형 기본값인 0으로 각각 초기화 되어있음.
	
	boolean[] arr3 = new boolean[2];
	System.out.println(Arrays.toString(arr3)); // [false, false]
	// 기본값 false
	
	String[] arr4 = new String[3];
	System.out.println(Arrays.toString(arr4)); // [null, null, null]
	// 참조형 기본값 null
	
	// 배열 선언과 동시에 (할당 및) 초기화
	char[] arr5 = {'A', 'B', 'C', 'D', 'E'};
	// {} (중괄호) 는 배열의 리터럴 표기법
	
	System.out.println(Arrays.toString(arr5)); // [A, B, C, D, E]
}

Arrays 클래스
Java 에서 제공하는 배열과 관련된 기능을 모아둔 클래스

Arrays.toString(배열명) : 모든 요소 값을 출력

배열 복사

얕은 복사 (shallow)

객체의 주소 값만 가져와 참조형 변수에 저장하고 하나의 객체를 두 변수가 참조하는 것

문제점

int[] arr1 = new int[4];
int[] arr2 = arr1;

arr2[1] = 400;
arr1[1]의 값도 변함
복사한 배열(arr2)을 수정하게 될 경우
원래 배열(arr1) 또한 수정되는 결과를 얻게 됨

얕은 복사 사용 예

public void shallowCopy() {
	
	int[] arr = {1, 2, 3, 4, 5};
	
	int[] copyArr = arr;
	
	System.out.println("변경 전");
	System.out.println("arr : " + Arrays.toString(arr));
	System.out.println("copyArr : " + Arrays.toString(copyArr));

	copyArr[2] = 999;
	
	System.out.println("변경 후");
	System.out.println("arr : " + Arrays.toString(arr));
	System.out.println("copyArr : " + Arrays.toString(copyArr));
}
변경 전
arr : [1, 2, 3, 4, 5]
copyArr : [1, 2, 3, 4, 5]
변경 후
arr : [1, 2, 999, 4, 5]
copyArr : [1, 2, 999, 4, 5]

깊은 복사 (deep)

새로운 배열 객체를 생성하여 기존 배열의 데이터를 복사하는 것 (주소값 다름)

깊은 복사 하는 방법

int[] arr = {1, 2, 3, 4, 5}; // 원본
System.out.println(arr); // [I@30c7da1e

// 1. for문을 이용한 깊은 복사
int[] copyArr1 = new int[arr.length]; // 5칸 짜리 배열 생성

for (int i = 0; i < arr.length; i++) {
	copyArr1[i] = arr[i];
}
System.out.println(copyArr1); //[I@5b464ce8

// 2. System.arraycopy(원본배열, 원본 복사 시작 인덱스,
//                     복사배열, 복사 배열의 삽입 시작 인덱스, 복사 길이);

int[] copyArr2 = new int[arr.length]; // 5칸 짜리 배열 생성

System.arraycopy(arr, 0, copyArr2, 0, arr.length);
System.out.println(copyArr2); // [I@39ba5a14

// 3. 복사할 배열 참조변수 = Arrays.copyOf(원본배열, 복사할 길이);
int[] copyArr3 = Arrays.copyOf(arr, arr.length);
System.out.println(copyArr3); // [I@30c7da1e

System.out.println("arr : " + Arrays.toString(arr));
System.out.println("copyArr1 : " + Arrays.toString(copyArr1));
System.out.println("copyArr2 : " + Arrays.toString(copyArr2));
System.out.println("copyArr3 : " + Arrays.toString(copyArr3));

arr2 = arr1.clone();
// 사용하지 않는 걸 권장

연습문제

배열을 이용한 중복 데이터 제거 + 정렬

  1. 1 ~ 45 사이 중복되지 않은 난수 6개 생성
  2. 생성된 난수가 오름차순으로 정렬 (낮은 숫자 -> 높은 숫자)

1) 정수 6개를 저장할 배열 선언 및 할당

2) 생성된 배열을 처음부터 끝까지 순차 접근하는 for문 작성

3) 1 ~ 45 사이 난수 생성
0.0 <= x < 1.0
0.0 <= x 45 < 45.0
1.0 <= x
45 + 1 < 46.0
1 <= (int)(x * 45 + 1) < 46
1 ~ 45

4) 생성된 난수를 순서대로 배열 요소에 대입

5) 중복 검사를 위한 for문 작성

6) 현재 생성된 난수와 같은 수가 앞쪽 요소에 있는지 검사

i 가 1씩 증가할 때마다 난수가 하나 생성됨.
-> 중복 값이 있으므로 난수를 새로 하나 더 생성해야됨
--> i 는 기본적으로 0 ~ 5까지 총 6회 반복되지만
i 값을 인위적으로 1 감소시켜서 총 7(n)회 반복되는 모양을 만든 것.
앞쪽에서 중복데이터를 발견하면 남은 값을 비교할 필요 없다.
-> 효율 향상을 위해서 검사하는 for 문 종료 break;
7) 오름차순 정렬
-> 선택, 삽입, 버블, 퀵 등등
--> 자바가 정렬 방법을 미리 만들어서 제공하고 있음
Arrays.sort(배열명) : 배열 내 값들이 오름차순으로 정렬됨

public void createLottoNumber() {

	int[] lotto = new int[6];
	
	for (int i = 0; i < lotto.length; i++) {
		
		int random = (int)(Math.random() * 45 + 1);

		lotto[i] = random;
		
		for(int x = 0; x < i; x++) {
			
			if(random == lotto[x]) {
				
				i--;

				break;

			}
		}
	}
	
	Arrays.sort(lotto);
	System.out.println(Arrays.toString(lotto));
}

0개의 댓글