# JAVA ] Ch 05. 배열

uuuu.jini·2022년 2월 2일
0

JAVA -자바의 정석

목록 보기
4/18
post-thumbnail

깃허브 링크

목차

  1. 배열
  2. String 배열
  3. 다차원 배열

1. 배열 [Array]

1.1] 배열(array)이란?

배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것 이다. 서로 다른 타입의 변수들로 구성된 배열은 만들수 없다. int[] score = new int[5] 에서 변수 score는 ㄱ밧을 저장하기 위한 공간이 아닌 참조변수일 뿐이다.

1.2] 배열의 선언과 생성

원하는 타입의 변수를 선언하고 변수 또는 타입에 배열임을 의미하는 대괄호[]를 붙이면 된다. 타입뒤에나 변수이름 뒤에 붙여도 된다. 타입[] 변수이름; 과 같이 사용한다.

  • 배열의 생성 : 배열을 선언한 다음에는 배열을 생성해야 한다. 배열을 생성해야만 비로서 값을 저장할 수 있는 공간이 만들어진다. 연산자 new와 함께 배열의 타입과 길이를 지정해 주어야 한다.
타입[] 변수이름; // 배열을 선언
변수이름  = new 타입[길이]; // 배열을 생성 ( 실제 저장공간을 생성 ) 
int[] score;
score = new int[5];
타입[] 변수이름 = new 타입[길이];
int[] score = new int[5];

1.3] 배열의 길이와 인덱스

생성된 배열의 각 저장공간을 배열의 요소(element)라고 하며, 배열이름[인덱스]의 형식으로 배열의 요소에 접근한다. 인덱스는 배열의 요소마다 붙여진 일련번호 로 범위는 0부터 배열의길이-1 까지 이다.

배열에 값을 저장하고 읽어오는 방법은 배열이름[인덱스]를 사용한다. score[2] = 1000; int value = score[3]

배열의 index로 상수 대신 변수나 수식을 사용할 수 있다.

	for( int i = 0;i < 5 ;i++ ) {
    	score[i] = i+10;
	}

괄호[]안에 수식이 포함이 된경우에는 이 수식이 먼저 계산된다.

배열을 다룰 때 한가지 주의할 점은 index의 범위를 벗어난 값을 index로 사용하지 않아야 한다는 것이다. 유효한 범위를 벗어난 값을 인덱스로 사용하는 것은 가장 흔한 실수이다. 컴파일러는 이러한 실수를 걸러주지 못한다. 그래서 유효한 범위를 사용하는 것은 전적으로 프로그래머의 책임이다. 유효하지 않은 값을 범위로 사용하는 경우 컴파일을 마쳤더라고 실행 시에 에러가 발생한다.( ArrayIndexOutfOfBoundsException)

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException

배열의 인덱스가 유효한 범위를 넘었다는 뜻으로 해당 배열의 길이와 인덱스를 확인해보아야 한다.

배열의 길이

배열의 길이는 배열의 요소의 개수,값을 저장할 수 있는 공간의 개수이다. 양의 정수이어야 하며 최대값은 int타입의 최대값, 약 20억이다. 배열의 길이는 int범위의 양의 정수(0도 포함)이어야 한다

배열이름.length

자바에서는 배열의 길이를 별도로 관리하며 배열이름.length를 통해서 정보를 얻을 수 있다.

	int[] arr = new int[5];
    int tmp = arr.length;

배열은 한번 생성하면 길이를 변경할 수 없기 때문에 배열이름.length는 상수이다. 즉 , 값을 읽을수만 있을뿐 값을 변경할 수는 없다. for문으로 배열의 요소를 반복하고 싶은 경우에 조건식에서 length를 사용하는 것이 효율적이다.

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

배열의 길이 변경하기

배열에 저장할 공간이 부족한 경우
1. 더 큰 배열을 새로 생성한다.
2. 기존 배열의 내용을 새로운 배열에 복사한다.

위의 방법을 사용한다. 이러한 작업들은 비용이 많이 들기 때문에 처음부터 배열의 길이를 넉넉하게 잡아줘서 새로 배열을 생성해야하는 상황을 적게 만들어야 하지만, 너무 크게 잡으면 메모리를 낭비하게 된다.

1.4] 배열의 초기화

배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되지만 해당 초기화 값을 지정해줄 수 있다. 원하는 값을 지정하려면 각 요소마다 값을 지정해줘야한다. 배열의 길이가 큰경우에는 for문을 사용하는 것이 좋다. ( 일정한 규칙이 있어야 가능 )

자바에서는 다음과 같은 초기화 방법을 제공한다.

	int[] score = new int[]{10,20,30,40,50};

저장할 값들을 괄호{}안에 쉼표로 구분해서 나열하면 되며, 괄호안의 값의 개수에 의해 자동으로 배열의 길이가 결정된다.( []안에 길이 안써줘도 된다. )

  • new int[]의 생략이 가능하다. ( 선언과 생성을 따로하는 경우 제외 )
  • 매개변수로 배열을 받는 경우에도 new int[]를 생략할 수 있다.
  • 괄호안에 아무런 숫자를 넣지 않은 경우 길이가 0인 배열이 생서된다.

배열의 출력

배열에 저장된 값을 확인 할 때도 for문을 사용한다. 더 간단한 방법은 Arrays.toString(배열이름)을 사용하는 것이다. 이 메서드는 해당 배열의 모든 요소를 [첫번째 요소, 두번째 요소,...] 와 같은 형식의 문자열로 반환한다. 배열을 바로 출력하는 경우에는 배열의 참조변수가 출력이 된다. ( 예외적으로, char배열은 println메소드로 출력하면 각 요소가 구분자 없이 그대로 출력된다. )

1.5] 배열의 복사

배열은 한번 생성시 그 길이를 변경할 수 없으므로, 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로 부터 내용을 복사해야한다. 배열을 복사하는 방법에는 두가지가 있다.

첫번째는 for문을 이용해서 배열을 복사하는 방법이다.

	int[] arr = new int[5];
    int[] tmp = new int[arr.length*2];
    
    for( int i = 0;i<arr.length;i++){
    	tmp[i] = arr[i]; 
	}
    
    arr =tmp ; 참조변수 arr이 새로운배열을 가리키게 된다.
    // tmp와 arr는 같은 배열을 가리키게 된다. 

이러한 작업은 꽤나 비용이 많이 들어가게 된다.

두번째는 System.arraycopy() 를 이용하여 복사를 하는 것이다. 보다 간단하고 빠르게 배열을 복사할 수 있다. 지정된 범위의 값들을 통째로 복사하기 때문이다. arraycopy()메소드를 호출할때는 어느배열의 몇번째 요소에서 어느 배열의 몇번째 요소로 몇개의 값을 복사할 것인지 지정해주어야 한다.

	System.arraycopy(num,0,newNum,0,num.length);
    //num[0]에서 newNum[0]으로 num.length개의 데이터를 복사

이때, 복사하려는 배열의 위치가 적절하지 못하여 복사하려는 내용보다 여유공간이 적으면 에러가 발생한다.

1.6] 배열의 활용

여러가지 예제를 통해 배열을 화용하는 법을 배운다.

총합과 평균

package ch05;

public class ArrayEx5 {

	public static void main(String[] args) {
		int sum = 0;
		float average = 0f;
		
		int[] score = {100,88,100,100,90};
		
		for( int i = 0; i< score.length;i++) {
			sum += score[i];
		}
		average = sum/(float)score.length;
		
		System.out.println("총점 : " + sum);
		System.out.println("평균: " + average);
	}

}

최대값과 최소값

package ch05;

public class ArrayEx6 {

	public static void main(String[] args) {
		
		int[] score = {79,88,91,33,100,55,95};
		
		int max = score[0];
		int min = score[0];
		
		for(int i = 0;i<score.length;i++) {
			if(max<score[i]) {
				max = score[i];
			}
			if(min>score[i]) {
				min = score[i];
			}
			
		}
		
		System.out.println("최대값: " + max);
		System.out.println("최소값: " + min);
	}

}

섞기(shuffle)

package ch05;

public class ArrayEx7 {

	public static void main(String[] args) {
		int[] numArr = new int[10];
		
		for(int i = 0;i<numArr.length;i++) {
			numArr[i] = i;
			System.out.print(numArr[i]);
		
		}
		System.out.println();
		
		for(int i = 0;i<100;i++) {
			int n = (int)(Math.random()*10);
			int tmp = numArr[0];
			numArr[0] = numArr[n];
			numArr[n] = tmp;
		}
		
		for ( int i = 0;i<numArr.length;i++) {
			System.out.print(numArr[i]);
		}
	}

}
package ch05;

public class ArrayEx8 {

	public static void main(String[] args) {
		int[] ball = new int[45];
		
		for(int i = 0;i<ball.length;i++) {
			ball[i] = i+1;
			
		}
		
		int temp = 0;
		int j = 0;
		
		for(int i = 0;i<6;i++) {
			j = (int)(Math.random()*45);
			temp = ball[j];
			ball[j] = ball[i];
			ball[i] = temp;
		}
		for(int i = 0;i<6;i++) {
			System.out.printf("ball[%d] : %d%n", i,ball[i]);
		}
		
	}

}

임의값으로 배열 채우기

package ch05;

import java.util.Arrays;

public class ArrayEx9 {

	public static void main(String[] args) {
		int[] code = {-4,-1,3,6,11};
		int[] arr = new int[10];
		
		for(int i = 0;i<arr.length;i++) {
			int tmp = (int)(Math.random()*code.length);
			arr[i] = code[tmp];
		}
		
		System.out.println(Arrays.toString(arr));
	}

}

정렬하기(sort)

package ch05;

public class ArrayEx10 {

	public static void main(String[] args) {
		int[] numArr = new int[10];
		
		for(int i = 0;i<numArr.length;i++) {
			numArr[i] = (int)(Math.random()*10);
			System.out.print(numArr[i]);
		}
		System.out.println();
		
		for(int i = 0;i<numArr.length-1;i++) {
			boolean changed = false;
			for(int j = 0;j<numArr.length-i-1;j++) {
				if(numArr[j]>numArr[j+1]) {
					int temp = numArr[j];
					numArr[j] = numArr[j+1];
					numArr[j+1] = temp;
					changed = true;
				}
			}
			if(!changed) break;
			
			for(int k = 0;k<numArr.length;k++) {
				System.out.print(numArr[k]);
			}
			System.out.println();
		}
	}

}

빈도수 구하기

package ch05;

public class ArrayEx11 {
	public static void main(String[] args) {
		int[] numArr = new int[10];
		int[] counter = new int[10];
		
		for(int i = 0;i<numArr.length;i++) {
			numArr[i] = (int)(Math.random()*10);
			System.out.print(numArr[i]);
		}
		System.out.println();
		
		for(int i = 0;i<numArr.length;i++) {
			counter[numArr[i]]++;
		}
		
		for(int i = 0;i<counter.length;i++) {
			System.out.printf("counter[%d]: %d%n",i,counter[i]);
		}
	}
}

2. String 배열

2.1] String배열의 선언과 생성

배열의 타입이 String인 경우에도 다른 배열의 선언과 생성방법이 동일하다. String[] name = new String[3];참조형 변수의 기본값은 null이므로 각 요소의 값은 null로 초기화 된다.

2.2] String 배열의 초기화

String배열의 초기화도 다른 배열의 초기화와 동일한 방법으로 수행한다.

	String[] name = new String[3];
    name[0] = "kim";
    name[1] = "Park";
    name[2] ="Ti";
	
    String[] name = new String[]{"kim","Park","Yi"};
    String[] name = {"Kim","Park","Ti"};

기본형 배열이 아닌 참조형 배열인 경우 배열에 저장되는 것은 객체의 주소이다. 참조형 배열을 객체 배열이라고도 한다. ㅋ

2.3] char배열과 String 클래스

문자열이라는 용어는 '문자를 연이어 늘어놓은 것'으로 문자배열인 char배열과 같은 뜻이다. 그런데 자바에서는 char배열이 아닌 String클래스를 사용한다. String클래스가 char배열에 기능(메서드)를 추가한 것 이기 때문이다. 즉 , 객체지향언어인 자바에서는 char배열과 그에 관련된 기능들을 함께 묶어서 다룰 수 있게 한다. ( 서로 관련된 것들끼리 데이터와 기능을 구분하지 않고 함께 묶는 것이다. )

String객체(문자열)은 읽을 수 만 있을 뿐 내용을 변경할 수 없다.

	String str = "java";
    str = str + "8"; // str에 '8'을 추가한 것 같지만 새로운 문자열이 str에 저장된다. 

위의 코드와 같이 작성하는 경우 문자열은 변경이 불가능하므로 새로운 내용의 문자열이 생성된다.

String 클래스의 주요 메서드

  • char charAt(int index) : 문자열에서 해당 위치(index)에 있는 문자를 반환한다.
  • int length() : 문자열의 길이를 반환한다.
  • String substirng(int from,int to) : 문자열에서 해당 범위(from~to)에 있는 문자열을 반환한다. to는 범위에 포함 안됨
  • boolean equals(Object obj) : 문자열의 내용이 obj와 같은지 확인한다. ( true,false), 문자의 대소문자를 구분한다. ( 대소문자를 구분하지 않고 비교하려면 equlasIgnoreCase()를 사용한다.
  • char[] toCharArray() : 문자열을 문자배열로 변환해서 반환한다.
	char[] chArr = {'A','B','C'};
    String str = new String(chArr); // char -> string
    char[] tmp = str.toCharArray(); // string -> char

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

Scanner 클래스의 nextLine()외에도 화면을 통해 사용자로부터 값을 입력받을 수 있는 간단한 방법이 있다. 커맨드라인을 이용한 방법인데, 프로그램을 실행할 때 클래스 이름 뒤에 공백문자로 구분하여 여러개의 문자열을 프로그램에 전달 할 수 있다. 만일 실행할 프로그램의 main메소드가 담긴 클래스의 이름 MainTest라고 가정하면 다음과 같이 실행할 수 있다. java MainTest abc 123
커맨드라인을 통해 입력을 받은 두 문자열은 String배열에 담겨서 MainTest클래스의 main의 매개변수 args로 전달된다. main메서드내에서 args[0]과 args[1] 같은 방식으로 문자열에 접근할 수 있다.

커맨드라인에서 입력된 매개변수는 공백문자로 구분하기 때문에 입력될 값에 공백이 있는 경우 큰따옴표로 감싸주어야 한다. 숫자를 입력해도 숫자가 아닌 문자열로 처리를 한다. ( Integer.parseInt() 로 변경 )

커맨드라인에 매개변수를 입력하지 않으면 크기가 0인 배열이 생성되어 args,length의 값은 0이 된다.

커맨드라인으로 java 실행 참고 자료


3. 다차원 배열

메모리의 용량이 허용하는 한, 차원의 제한은 없지만, 주로 1,2차원 배열이 사용된다.

3.1] 2차원 배열의 선언과 인덱스

2차원배열의 선언은 1차원 배열과 같지만 [] 만 하나더 들어간 것이다. 타입[][] 변수이름 타입 변수이름[][] 타입[] 변수이름[]

2차원 배열은 주로 테이블 형태의 데이터를 담는다. 타입[][] 변수명 = new 타입[행][열] 로 선언한다. 배열을 생성하면, 배열의 각 요소에는 배열요소타입의 기본값이 저장된다.

2차원 배열의 index

2차원 배열은 행과 열로 구성되어 있기 때문에 index도 행과 열에 각각 하나씩 존재한다. 행과 열의 범위 모두 0~행/열의 길이-1이다. 2차원배열의 각요소에 접근하는 방법은 배열이름[행index][열index] 이다.

3.2] 2차원 배열의 초기화

2차원 배열도 괄호{}를 사용해서 생성과 초기화를 동시에 할 수 있다. 1차원 배열보다 괄호{}를 한번 더써서 행별로 구분해 준다.

	int[][] arr = {
    		{1,2,3},
            {4,5,6}
	}

2차원 배열은 '배열의 배열'로 구성되어 있다. 즉 여러개의 1차원 배열을 묶어서 또 하나의 배열로 만든 것이다. 그러므로 for문을 이용하여 2차원 배열을 초기화 하는 경우는 밑과 같다.

 	for ( int i = 0;i<score.length;i++){ //행 반복 횟수 - score.length
    	for(int j = 0;j<score[i].length;j++){ //열 반복 횟수 - score.length[i]
        	score[i][j] = 10;
		}
	}

3.3] 가변 배열

2차원 이상의 다차원 배열을 생성 할 때 전체 배열의 차수 중 마지막 차수의 길이를 지정하지 않고, 추후에 각기 달느 길이의 배열을 생성함으로써 고정된 형태가 아닌 보다 유동적인 가변 배열을 구성할 수 있다. (각기 다른 길이의 배열을 행으로 갖는다. )

	int[][] score = new int[3][];
    score[0] = new int[3];
    score[1] = new int[2];
    score[2] = new int[1];

생성과 초기화도 위의 방법과 동일하게 가능하다.

profile
멋쟁이 토마토

0개의 댓글