안녕하세요!

FE 개발자 유진주입니다.

Language/JAVA

[자바의 정석] Chapter 5. 배열

ypearl 2023. 5. 10. 12:57

배열이란?

: 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것

int [] score = new int[5];

✨ 각 저장공간에 모두 이름을 붙이는 대신에 참조변수의 이름을 붙이고,

참조변수를 통해서 이 공간을 다루게 됨.

(자동적으로 인덱스 순서에 따라 이름이 만들어지기 때문에,

우리가 변수처럼 일일이 각 저장공간의 이름을 붙일 필요 X)

 

<특징>

1) 같은 타입

2) 연속적

 

배열의 선언과 생성

배열 선언과 변수 선언은 차이 有

-> 변수는 선언하는 순간 저장공간 만들어짐,

배열의 선언은 실제 배열의 저장공간들이 만들어지는 것이 아닌, 배열을 다루기 위한 참조 변수가 만들어지는 것.

 

<배열 선언  ㅡ 배열을 다루기 위한 참조변수의 선언>

선언방법 선언 예
타입[] 변수이름;    // Java 스타일 int[] score;
String[] name;
타입 변수이름[];   // C언어 스타일 int score[];
String name[];
타입[] 변수이름;			  // 배열을 선언 (배열을 다루기 위한 참조변수 선언)
변수이름 = new 타입[길이];	// 배열을 생성 (실제 저장공간을 생성)

int[] score;			   // int타입의 배열을 다루기 위한 참조변수 score 선언
score = new int[5];		   // int타입의 값 5개를 저장할 수 있는 배열 생성

 

배열의 인덱스

<배열의 인덱스 ㅡ 각 요소(저장공간)에 자동으로 붙는 (일련)번호>

class Ex5_1 {
	public static void main(String[] args) {
    	int[] score;		  // 1. 배열 score를 선언 (참조변수)
        score = new int[5];	  // 2. 배열의 생성 (int 저장공간 X5)
        
        int[] score = new int[5]; 	// 배열의 선언과 생성을 동시에
        score[3] = 100;
    }
}

 

배열의 길이

배열이름.length ㅡ 배열의 길이(int형 상수)

int[] arr = new int[5];	// 길이가 5인 int 배열
int   tmp = arr.length; // arr.length의 값은 5이고 tmp에 5가 저장된다.

🚨 배열은 한번 생성하면, (실행 중에는) 그 길이를 바꿀 수 없다!

1) 왜 바꿀 수 없는가?

: 배열은 연속적이기에 공간을 늘리고자 할 때, 그 뒤에 늘릴 공간이 없을 수 있다.

만약 공간이 부족할 경우, 원래 있던 것을 다른 곳으로 옮겨야 하는데

그냥 크기를 못 늘리게 하고 필요한 곳으로 옮기도록 규칙이 정해져 있음?

2) 공간이 부족해서 늘리고 싶으면 어떻게 되는 것인가?

: 공간을 크게 늘릴 수 없기 때문에 새로운 큰 배열을 만들어 기존의 배열에 있는 내용을 복사한다.

for (int i=0; i<6; i++){
	System.out.println(score[i]);
}

int[] score = new int[5];	// 배열의 길이를 6에서 5로 변경

for (int i=0; i<score.length; i++){	  // 조건식을 변경하지 않아도 됨
	System.out.println(score[i]);
}

⛔ 인데스 범위를 벗어나는 에러 주의

 

배열의 초기화

: 배열의 각 요소에 처음으로 값을 저장하는 것

* 자동 초기화: int의 경우 기본값이 0으로 모두 초기화

 

<배열의 초기화 방법>

방법1: int[] score = new int[]{ 50, 60, 70, 80, 90 };
방법2: int[] score = { 50, 60, 70, 80, 90 };	// new int[]를 생략할 수 있음

💥 주의
방법2가 방법1보다 간단하나(방법2만 기억해도 된다),
방법2의 경우에는 두 줄로 그대로 나누어 쓸 경우 에러 발생!

int[] score;
score = { 50, 60, 70, 80, 90 };	          // 에러. new int[]를 생략할 수 없음
score = new int[]{ 50, 60, 70, 80, 90 };  // OK.

 

배열의 출력

int[] iArr = { 100, 95, 80, 70, 60 };	// 배열을 가리키는 참조변수 iArr의 값을 출력한다.
System.out.println(iArr); 	// [I@14318bb와 같은 형식의 문자열이 출력된다.
✨ [ = 배열의미, I = int의미, @ = 위치의미 // 정리하면, "~주소에 있는 int 배열이다"라는 의미

예외.
char[] chArr = { 'a', 'b', 'c', 'd' };
System.out.println(chArr);	// abcd가 출력된다.
1️⃣ for문 사용	// 배열의 요소를 순서대로 하나씩 출력
for (int i=0; i<iArr.length; i++) {
	System.out.println(iArr[i]);
}

2️⃣ Arrays 클래스 이용 //  배열 iArr의 모든 요소를 출력
System.out.println(Arrays.toString(iArr));   //  [100, 95, 80, 70, 60]이 출력됨

toString 메소드 ㅡ 배열의 내용을 문자열로 만들어서 방어해준다.

✨ 참고
ctrl+shift+o : 자동으로 import문 추가

 

배열의 활용

- 총합과 평균 : 배열의 모든 요소를 더해서 총합과 평균을 구한다.

   ㄴ float 형변환 주의 -> 하나만 float 형변환 해주면 된다!

- 최대값과 최소값 : 배열의 요소 중에서 제일 큰 값과 제일 작은 값을 찾는다.

- 섞기 : 배열의 요소의 순서를 반복해서 바꾼다. (숫자 섞기, 로또번호 생성)

import java.util.Arrays;

class Ex5_4 {	#숫자 섞기
	public static void main(String[] args) {
    	int[] numArr = {0,1,2,3,4,5,6,7,8,9};
        System.out.println(Arrays.toString(numArr));
        
        for (int i=0; i<100; i++){
        	int n=(int)(Math.random()*10);	// 0~9 중의 한 값을 임의로 얻는다.
            int tmp=numArr[0];
            numArr[0]=numArr[n];
            numArr[n]=tmp;			// numArr[0]과 numArr[n]의 값을 서로 바꾼다.
        }
        System.out.println(Arrays.toString(numArr));
    }	// main의 끝
}
class Ex5_5 {	#로또번호 생성
	public static void main(String[] args) {
    	// index : 0 ~ 44
        int[] ball = new int[45];	// 45개의 정수값을 저장하기
        
        // 배열의 각 요소에 1~45의 값을 저장한다.
        for(int i=0; i<ball.length; i++)
        	ball[i] = i+1;		// ball[0]에 1이 저장된다.
            
        int tmp = 0;	// 두 값을 바꾸는데 사용할 임시변수
        int j = 0;		// 임의의 값을 얻어서 저장할 변수
        
        // 배열의 i번째 요소와 임의의 요소에 저장된 값을 서로 바꿔서 값을 저장한다.
        // 0번째부터 5번째 요소까지 모두 6개만 바꾼다.
        for(int i=0; i<6; i++){
        	j = (int)(Math.random() * 45); // 0 ~ 44범위의 임의의 값
            tmp = ball[i];
            ball[i] = ball[j];
            ball[j] = tmp;
        }
    }
}

 

String 배열의 선언과 생성

String[] name = new String[3];	// 3개의 문자열을 담을 수 있는 배열을 생성한다.

🚨 String은 참조형이므로 기본값으로 null이 들어간다.
자료형 기본값
boolean false
char '\u0000'
byte, short, int 0
long 0L
float 0.0f
double 0.0d 또는 0.0
참조형 (String) null
String[] name = new String[] { "Kim", "Park", "Yi" }; // 이건 무시해도 된다!
String[] name = { "Kim", "Park", "Yi" };

 

String 클래스

1. String 클래스는 char[]와 메서드(기능)를 결합한 것

String 클래스 = char[] + 메서드(기능)    -> 서로 관련있기 때문!

 

2. String 클래스는 내용을 변경할 수 없다. (read only 읽기만 가능)

 

메서드 설명
char charAt(int index) 문자열에서 해당 위치(index)에 있는 문자를 반환한다.
int length() 문자열의 길이를 반환한다.
String substring(int from, int to) 문자열에서 해당 범위(from~to)의 문자열을 반환한다.(to는 포함 안 됨)
boolean equals(Object obj) 문자열의 내용이 같은지 확인한다. 같으면 결과는 true, 다르면 false
char[] toCharArray() 문자열을 문자배열(char[])로 변환해서 반환한다.
String str = "ABCDE";
char 	ch = str.charAt(3);	// 문자열 str의 4번째 문자 'D'를 ch에 저장.

String str = "012345";
String tmp = str.substring(1~4);  // str에서 index범위 1~4의 문자들을 반환 (마지막 to는 포함 안 됨)
System.out.println(tmp);	  // "123"이 출력된다.

String tmp2 = str.substring(1);	  // to를 안 적으면 1부터 끝까지~
System.out.println(tmp2);	  // "12345" 출력

 

커맨드 라인을 통해 입력받기

커맨드 라인에 입력한 값이 문자열 배열에 담겨서 전달된다.

- 공백을 기준으로 각 요소가 문자열로 받아져 문자열 배열이 된다.

- 이것이 참조변수 args에 전달.

cf. 매개변수를 입력하지 않은 경우, 길이가 0인 ("") 배열이 된다.

public class Ex5_7 {

	public static void main(String[] args) {
		System.out.println("매개변수의 개수:"+args.length);
		for(int i=0; i<args.length; i++) {
			System.out.println("args["+i+"]=\""+args[i]+"\"");
		}
	}
}

✨ Eclipse 커맨드 창 입력 받는 방법
: Run(초록 재생버튼) > Run Configurations > Main 오른쪽 Arguments > Program arguments에 입력

<출력결과>
매개변수의 개수:3
args[0]="abc"
args[1]="123"
args[2]="Hello World"

✨ Window 커맨드 창 입력 받는 방법
: 윈도우키+R > cmd 열기 > 이클립스에서 alt+Enter (소스파일 경로 찾기)
> Location에서 java 파일 위치 찾기 > 그 위의 단계에서 class 파일 찾고 위치 복사 (C:\websys\2111490\_ch03\bin)
> 커맨드 창에 cd C:\websys\2111490\_ch03\bin 작성
> dir > 입력

 

✨ Window 커맨드 창 입력 받는 방법

 

2차원 배열

테이블 형태의 데이터를 저장하기 위한 배열

* 2차원 배열은 1차원 배열이 여러 개 모인 것

* 3차원 배열은 2차원 배열이 여러 개 모인 것

int[][] score = new int[4][3];	// 4행 3열의 2차원 배열을 생성한다. (12개)

 

2차원 배열의 인덱스

score[0][0] = 100;			// 배열 score의 1행 1열에 100을 저장
System.out.println(score[0][0]);	// 배열 score의 1행 1열의 값을 출력

 

2차원 배열의 초기화

int[][] arr={ {1,2,3}, {4,5,6} };	// new int[][]가 생략됨 (써도 무방)

int[][] arr= {
		{1,2,3},
                {4,5,6}
             };				// 보다 직관적!

 

2차원 배열 예제

public class Ex5_8 {

	public static void main(String[] args) {
		int[][] score= {
				{100,100},
				{20,20,20,20},
				{30,30},
				{40}
		};
		int sum=0;
		
		for(int i=0; i<score.length; i++) {
			for(int j=0; j<score[i].length; j++) {
				System.out.printf("score[%d][%d]=%d%n", i, j, score[i][j]);
				
				sum+=score[i][j];
			}
		}
		System.out.println("sum="+sum);
	}
}


<출력결과>
score[0][0]=100
score[0][1]=100
score[1][0]=20
score[1][1]=20
score[1][2]=20
score[1][3]=20
score[2][0]=30
score[2][1]=30
score[3][0]=40
sum=380

🚨 꼭 정사각형 배열로 이루어지는 것은 아니다! 각 1차원 배열의 길이가 다 다를 수도 있다.

 

스스로 해보기

- 예제 9번

public class Ex5_9 {

	public static void main(String[] args) {
		int[][] score= {
				{100,100,100},
				{20,20,20},
				{30,30,30},
				{40,40,40},
				{50,50,50}
					   };
		
		System.out.println("==================================");
		System.out.println("번호  국어  영어  수학  총점  평균");
		System.out.println("==================================");
		for(int i=0; i<score.length; i++) {
			int sum=0;
			System.out.printf("%3d", i+1);
			for(int j=0; j<score[i].length; j++) {
				sum+=score[i][j];
				System.out.printf("%5d", score[i][j]);
			}
			
			System.out.printf("%5d", sum);
			System.out.printf("%5.0f", (sum/(float)score[i].length));
			System.out.print("\n");
		}
		System.out.println("==================================");
		System.out.print("총점:");
		for(int j=0; j<score[0].length; j++) {
			int total=0;
			for(int i=0; i<score.length; i++) {
				total+=score[i][j];
			}
				System.out.printf("%5d", total);
		}
	}
}

<출력결과>
==================================
번호  국어  영어  수학  총점  평균
==================================
   1  100   100   100   300   100
   2   20    20    20    60    20
   3   30    30    30    90    30
   4   40    40    40   120    40
   5   50    50    50   150    50
==================================
총점: 240   240   240

 

- 예제 10번

import java.util.Scanner;

public class Ex5_10 {

	public static void main(String[] args) {
		String[][] words= {
				{"comply", "준수하다"},
				{"attire", "복장"},
				{"policy", "보험"}
		};
		
		Scanner sc=new Scanner(System.in);
		
		for(int i=0; i<words.length; i++) {
			System.out.printf("Q%d. %s의 뜻은 무엇입니까?", i+1, words[i][0]);
			
			String sub=sc.nextLine();
			
			if(sub.equals(words[i][1])) {
				System.out.printf("정답입니다!%n%n");
			}
			else {
				System.out.printf("틀렸습니다! 정답은 %s입니다:(%n%n", words[i][1]);
			}
		}
	}
}

출력결과

 

String 클래스

* 문자열: 여러 개의문자 나열

1. String 클래스는 char[]와 메서드(기능)를 결합한 것

String 클래스 = char[] + 메서드(기능)     // 서로 관련이 있기 때문

2. String 클래스는 내용을 변경할 수 없다. (read only)   // 읽기만 가능

 

메서드 설명
char charAt(int index) 문자열에서 해당 위치(index)에 있는 문자를 반환한다.
int length() 문자열의 길이를 반환한다.
String substring(int from, int to) 문자열에서 해당 범위(from~to)의 문자열을 반환한다.(to는 포함 안 됨, to 생략시 str.length()로 해석)
boolean equals(Object obj) 문자열의 내용이 같은지 확인한다. 같으면 결과는 true, 다르면 false (※ 문자열 비교는 '==' 사용 금지)
char[] toCharArray() 문자열을 문자배열(char[])로 변환해서 반환한다.
String str = "ABCDE";
char ch = str.charAt(3);	// 문자열 str의 4번째 문자 'D'를 ch에 저장.
System.out.println(str.length());	// 출력값 5

String str = "012345";
String tmp = str.substring(1,4);	// str에서 index 범위 1~3의 문자들을 반환
System.out.println(tmp);	// "123"이 출력된다.

 

Arrays 클래스로 배열 다루기

배열의 비교와 출력 - equals(), toString()

int[] arr = {0,1,2,3,4};
int[][] arr2D = {{11,12},{21,22}};

System.out.println(Arrays.toString(arr));	// [0,1,2,3,4]
System.out.println(Arrays.deepToString(arr2D));	// [[11,12],[21,22]]


String[][] str2D = new String[][]{{"aaa", "bbb"}, {"AAA", "BBB"}};
String[][] str2D2 = new String[][]{{"aaa", "bbb"}, {"AAA", "BBB"}};

System.out.println(Arrays.equals(str2D, str2D2));	// false
System.out.println(Arrays.deepEquals(str2D, str2D2));	// true

💥 다차원 배열의 경우 deepToString, deepEquals 메소드 사용하기!

 

배열의 복사 - copyOf(), copyOfRange()

int[] arr = {0,1,2,3,4};
int[] arr2 = Arrays.copyOf(arr, arr.length);	// arr2=[0,1,2,3,4]
int[] arr3 = Arrays.copyOf(arr, 3);	// arr3=[0,1,2]
int[] arr4 = Arrays.copyOf(arr, 7);	// arr4=[0,1,2,3,4,0,0]
int[] arr5 = Arrays.copyOf(arr, 2, 4);	// arr5=[2,3]
int[] arr6 = Arrays.copyOf(arr, 0, 7);	// arr6=[0,1,2,3,4,0,0]

 

배열의 정렬(오름차순) - sort()

int[] arr = { 3, 2, 0, 1, 4 };
Arrays.sort(arr);	// 배열 arr을 정렬한다.
System.out.println(Arrays.toString(arr));	// [0, 1, 2, 3, 4]