[Java] 배열

Jeini·2022년 10월 3일
0

☕️  Java

목록 보기
3/59
post-thumbnail

숫자나 문자열을 담을 수 있는 변수를 배웠다.
많은 데이터의 평균을 구한다던지, 프로그램이 커질수록 많은 변수를 사용해야 한다.
이제 배울 배열은, 변수를 보다 편리하게 사용하기 위한 방법이다.
배열을 사용함으로써 한번에 많은 변수를 처리할 수 있다.

💡 배열


동일 종류의 복수 데이터를 순서대로 저장하는 데이터 구조

배열의 최초의 요소는 0번이다.

✏️ 배열의 작성 순서

1. 기본적인 배열

int[] arr = new int[3]; // [3]이 부분이 길이가 됨 
arr[0] = 3;
arr[1] = 4;
arr[2] = 5;

가장 기본적이고 많이 쓴다.

2. 정해진 숫자가 있을 때.

int[] arr = {3, 4, 5};

선언과 정의를 분리할 수 없다.
안에 들어갈 원소들을 다 알고 있어야 한다.
그래서 실제로 그렇게 많이 쓰이진 않는다.

  1. 이름과 같이 쓸 때, 파라미터안에 넣을 때.
int[] arr = new int[] {3, 4, 5};
  • 첫 번째 식
public class Main {
	public static void main(String[] args) {
    
    int[] score; // 배열변수의 선언
        
    score = new int[5]; // 요소의 작성과 대입
    } // 5개짜리 상자를 만드는 것이라고 생각!
}
  • 두 번째 식 (한줄로 쓰는 것이 더 일반적임)
public class Main {
	public static void main(String[] args) {
    	
        int[] score = new int[5];
    
    }
}

✏️ 배열의 길이 구하기

public class Main {
	public static void main(String[] args) {
		
        int[] score = new int[5];
        int count = score.length;
        System.out.println("요소의 수 " + count);        
    }
}

❗️ int count = score.length;
배열로 만든 것은 length라고 하는 내부적인 값이 있는데,
그 값을 통해 길이를 얻을 수 있다.

✏️ 배열의 요소에 값을 대입

public class Main {
	public static void main(String[] args) {
    	
        int[] score;
        score = new int[5];
        score[1] = 30; // 두 번째 요소에 30 대입
        System.out.println(score[1]);    
    }
}

❗️ score[1] = 30;
[] 이 부분에 들어갈 숫자는 0 ~ 4까지이다.
당연히 5를 넣으면 에러가 난다.

✏️ 배열의 초기화

원래는 초기화 하지 않고 정수를 넣게 되면 에러가 난다.

public class Main {
	public static void main(String[] args) {
    	
        int x;
      
        System.out.println(x); // 컴파일 에러    
    }
}

변수를 사용하기 전에는 반드시 초기화를 해야 한다.
기존에 우리가 정수를 사용할 때,
선언을 하고 값을 넣지 않은 상황에서 println을 사용하게 되면 컴파일 에러가 난다.

하지만! 배열은 다르다.

public class Main {
	public static void main(String[] args) {
    
    // 배열의 요소는 자동으로 초기화된다.
    // 5개의 요소가 전부 0으로 초기화
    int score = new int[5];
    System.out.println(score[0]); // 에러아님!
    }
}

배열은 일반 int랑 다르게 5개짜리 공간을 확보하게 되면
저절로 0이 전부다 들어가 있다고 판단한다.
따라서 에러가 나지 않는다.

✏️ 생략기법

int[] score1 = new int[] {20, 30, 40, 50, 80};
int[] score2 = {20, 30, 40, 50, 80}; // 이 식이 일반적.

✏️ 배열과 예외

범위를 벗어난 요소를 이용할 때 예외(exception)가 발생한다.
예외: 에러

score[1] = 30; // 두 번째 값에 30 대입.

위에서 봤듯이,
[] 이 부분에 들어갈 숫자는 0 ~ 4까지이다.
당연히 5를 넣으면 에러가 난다.

java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds ...

💯 점수관리 프로그램


그냥 일반적으로 한 식

public class Normal {

	public static void main(String[] args) {
		
		int math = 20;
		int korean = 30;
		int science = 40;
		int english = 50;
		int society = 80;
		
		int sum = math + korean + english + society;
		
		int avg = sum / 5;
		
		System.out.println("합계: " + sum);
		System.out.println("평균: " + avg);
		
	}		
}

배열을 이용한 식

public class Test3 {

	public static void main(String[] args) {
		
		int[] score = {20, 30, 40, 50, 80};
		int sum = score[0] + score[1] + score[2] + score[3] + score[4];
		int avg = sum / score.length; 
		
		System.out.println("합계: " + sum);
		System.out.println("평균: " + avg);
		
	}
}

❗️ int sum = score[0] + score[1] + score[2] + score[3] + score[4];
0부터 하는 거 조심 ! 1부터 시작 아님 !!

❗️ int avg = sum / score.length;
length는 배열의 개수를 알려준다.
/ 5대신 length를 활용함으로써 숫자를 건드리지 않고 고정시킬 수 있다.

✔️ 배열 데이터를 모아서 취급

처음에 비해 코드가 많이 좋아졌다.
좀 더 개선해보자.
과목이 늘어났을 때에 합계를 구할 때 수정 할 부분들이 있다.
for문과 조합하여 해결할 수 있다.

💡 배열과 for문


public class Test3 {

	public static void main(String[] args) {
		
		int[] score = {20, 30, 40, 50, 80};
		
		for (int i = 0; i < score.length; i++) {
			System.out.println(score[i]);
		}		
	}
} // 20 ~ 80까지 출력.

✏️ 향상된 for문

		int[] score = {20, 30, 40, 50, 80};
		
		// 일반 for문
		for (int i = 0; i < score.length; i++) {
			System.out.println(score[i]);
		}
		// 향상된 for문(for each문)
		for (int value : score) {
			System.out.println(value);
		}
	}
}

❗️ for-each문
: for (int value : score) {...}
원래 for문은 앞에 인덱스를 다루는 변수를 활용하는데,
for each문은 실제 값을 넣는 변수를 사용한다.
score안에 있는 숫자를 하나하나 갖고오면서 반복한다.

💡 메모리와 변수


컴퓨터 내부에 변수가 할당된 모습.

  • int는 4바이트를 저장하니까 한칸이 메모리인 1바이트라고 봤을 때,
    차지하는 a가 메모리에 차지하게 된다.
  • 왼쪽의 숫자는 주소인데, 메모리안에는 주소가 있다.
  • 몇 번째 몇 번째 주소가 있는데, 실제로 이 값은 아니고 막 써놓은 것이다.
  • a는 맨앞에 있는 주소(빨간색)를 두고 컴퓨터가 값을 찾으러 다닐 수 있다.

💡 메모리와 배열


배열 변수에는 5개의 요소가 들어있는 것이 아니다.
최초의 요소의 주소(address 또는 reference)가 대입된다.

❗️int[] score = new int[5];를 실행했을 때의 메모리상의 모습
1. int형 요소를 5개 가지는 배열(파란색)이 메모리상에 작성 됨.
2. int[]형의 배열변수 score(주황색)가 메모리상에 작성됨.
3. score에 배열의 선두요소의 주소가 대입 됨.

❓ 프로그램에서 score[n]을 지정했을 때

  • score(사진상에서는 'a') 안에 들어있는 주소를 꺼내서, 배열 (선두요소)를 찾는다.
  • 찾은 배열의 선두요소로부터 n개 뒤쪽의 요소를 읽는다.
  • 실제로 score는 int의 5개의 요소를 다 가지고 있는 것이 아니다.

✏️ 참조 (reference)

배열처럼 변수명을 지정 했을 때, 그 값이 아니라 주소를 가리키는 것을 참조(reference)라고 한다.
그리고 그 변수를 참조형(reference type) 변수라고 한다.
int 나 boolean 같은 "기본형(primitive type)"변수와 구별된다.

✏️ 예시문제) 실행결과는?

변수 b는 변수 a와 같은 배열을 참조한다.

public class Test4 {
	public static void main(String[] args) {
		
		int[] a = {1, 2, 3};
		int[] b;
		b = a; // 1, 2, 3
		b[0] = 100; // 100, 2, 3
		System.out.println(a[0]);
	
	} // 결과값: 100
}
  • 이것을 이해하기 위해서는 메모리의 원리를 이해해야 한다.
  • a가 {1,2,3} 들어있고, b는 a이 값이 아니라, a의 주소를 저장한다.
    그래서 a와 b는 같은 주소로 저장되어 있다.
  • 그 주소는 각각 1,2,3이 저장된 곳을 나타낸다.
  • 그래서 b의 첫 번째 값에 100을 넣었을 때,
    똑같이 a의 첫 번째 값에 100이 들어간다.
    둘 다 배열의 첫 번째 값을 보고 있는 것이다.

✔️ 배열의 정리

"참조형" 변수는 "기본형" 과는 다르다고 했다.
배열의 경우도 마찬가지로 조금 다른 점들을 살펴 보자.

💡 가바지 컬렉션(garbage collection)

public class Main {
	public static void main(String[] args) {
    	boolean b = true;
        if (b == true) {
        	int[] i = {1, 2, 3}; //new가 생략되어 있는 것.
        }
    }
}

int[] i = {1, 2, 3};
new가 생략되어 있으므로, 블록이 끝나도 수명을 다하지 않고 살아있다.
이러한 것이 메모리 내의 쓰레기가 되는 것.

new로 확보된 요소들은 보통의 변수와 다르기 때문에,
블록이 끝나도 수명이 다하지 않는다.

블록 내에서 생성된 배열은 이 후 어떤 방법으로도 읽거나 쓸 수 없고 메모리를 차지하고 있다. 사실상 메모리 내의 쓰레기(gerbage)가 된다.

원래 이렇게 사용하지 않게 된 메모리는 프로그래머가 정리를 하여야 한다.
하지만 Java는 가비지 컬렉션 (GC, garbage collection)이라는 장치가 더 이상 사용되지 않는 메모리를 정리 해 준다.

💡 null

  • int[] 같은 참조형 변수에 대입하면, 이 변수는 아무것도 참조하지 않게 됨.
  • int형 같은 기본형 변수에 대입할 수 없음.
  • 원래 주소값을 가지고 있는데, 없애버리는 역할을 함.
  • 메모리에서 값이 제거가 됨.
public class Test4 {
	public static void main(String[] args) {
		
		int[] a = {1, 2, 3};
		a = null;
		a[0] = 10;
	
	} // 결과값: 에러(NullPointerException)
}

a는 1, 2, 3을 보고 있다가 여기서 null를 넣게 됨으로써, 이제 값을 보지 않게됨. 그래서 a에 10을 넣게 되더라도 아무것도 보지 못하게 되는 것.

💡 배열의 length와 문자열의 length()


  • String의 length()는 한글, 영문, 공백 관계없이 1문자로 카운트
  • 배열의 length와 비슷하지만 ()를 붙여야 한다.
public class Main {
	public static void main(String[] args) {
    	
        String s = "Java로 개발";
        System.out.println(s.length());
    }
}

💡 다차원 배열


3행 3열

2행 3열 Code

public class Test4 {
	public static void main(String[] args) {
		
		int[][] scores = new int[2][3]; //2행 3열
		scores[0][0] = 40;
		scores[0][1] = 50;
		scores[0][2] = 60;
		scores[1][0] = 80;
		scores[1][1] = 60;
		scores[1][2] = 70;
		
		System.out.println(scores[1][1]);
		
	} // 결과값: 60
}

✏️ 배열의 요소 수 표시 (다차원 배열 한번에 표시)

public class Test4 {
	public static void main(String[] args) {
		
		int[][] scores = { {10, 20, 30}, {30, 40, 50} };
		
		System.out.println(scores.length);
		System.out.println(scores[0].length);
		
	} // 결과값: 2 
    	    // 3
}

연관된 글
: Java 배열 정렬

profile
Fill in my own colorful colors🎨

0개의 댓글