본문 바로가기
프로그래밍 ( Programming )/JAVA

[JAVA] 배열

by Jayce_choi 2021. 6. 1.
반응형

JAVA에서도 배열이 존재하는데 데이터를 다루고 구조화시키기 위해서 매우 필수적인 개념입니다.

배열은 일반적으로 기본 변수를 각각 선언하는 게 아닌 여러 자료를 한 번에 처리하고 선언이 가능한 기능입니다. 

선언 방법
1. 자료형[] 배열 이름 = new 자료형 [개수];
2. 자료형 배열 이름[] = new 자료형 [];
ex) int [] studentIDs = new int [10];

초기화 방법
1. int [ ] studentIDs = new int [ ]{1,2,3};
2. int[ ] studentIDs = {101,103,104};
3. int[ ] studentIDs;
studentIDs = new int [ ]{1,2,3};

* 여기서 계속 [ ] 이거를 사용하는 것은 인덱스 연산자를 의미합니다. 인덱스 연산자의 기능은 배열 요소가 저장된 메모리 위치를 찾아주는 역할을 수행합니다.

잘못된 선언 방법 : int[ ] studentIDs = new int [3]{1,2,3}; // 숫자를 넣어주면 안 된다. 

예시

package array;

public class ArrayTest {

	public static void main(String[] args) {
		int[] num = new int[] {1,2,3};
		for(int i = 0; i<num.length;i++) {
			System.out.println(num[i]);
		}
	}
}
package array;

public class ArrayTest {

	public static void main(String[] args) {
		int[] num = new int[] {1,2,3};
		for(int i = 0; i<num.length;i++) {
			System.out.println(num[i]);
		}
	}
}

 

ASCII code 출력 예제 

package array;

public class CharArray {

	public static void main(String[] args) {
		char[] alphabets = new char[26];
		char ch = 'A';
		
		for(int i =0;i<alphabets.length;i++,ch++) {
			alphabets[i] = ch;
		}
		
		for(int i=0;i<alphabets.length;i++) {
			System.out.println(alphabets[i] + ", " + (int)alphabets[i]);
		}
	}
}

 

객체 배열 사용하기 

동일한 기본 자료형 변수 여러 개를 배열로 사용이 가능하듯이 참조 자료형 변수도 여러 개를 배열로 사용 가능합니다. 객체 배열은 int나 char 등 기본 자료형 배열과 사용 방법이 조금 다릅니다.

예제

package array;

public class Book {
	private String bookName;
	private String author;
	
	public Book() {} // 디폴트 생성자 
	
	public Book(String bookName, String author) {
		this.bookName = bookName;
		this.author = author;
	}
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public void showBookInfo() {
		System.out.println(bookName + "," + author);
	}

}
package array;

public class BookArray {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book[] data = new Book[5];
		
		for(int i =0;i<data.length;i++) {
			System.out.println(data[i]);
		}
	}
}

해당 코드를 실행하면 출력 값이 Null이 나오게 됩니다.

new Book [5]를 통해서 인스턴스 5개가 생성된 것처럼 나오겠지만 하지만 인스턴스 5개가 바로 생성된 것은 아닙니다. 그렇다면 생성된 것은 무엇일까요. 실제 생성된것은 인스턴스를 가리키는 주소 값을 담을 공간 5개를 생성한 문장과 동일합니다.
즉 결과적으로 Book 주소 값을 담을 공간이 5개가 만들어지고 자동으로 각 공간은 비어있다는 의미의 null 값으로 초기화가 됩니다.

이제 각 배열 요소에 인스턴스를 생성해보겠습니다.

package array;

public class BookArray2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book[] library = new Book[5];
		library[0] = new Book("태백산맥","조정래");
		library[1] = new Book("데미안","헤르만 헤세");
		library[2] = new Book("어떻게 살 것인가","유시민");
		library[3] = new Book("토지","박경리");
		library[4] = new Book("어린왕자","생텍쥐페리");
		
		for(int i=0;i<library.length;i++) {
			library[i].showBookInfo();
		}
		for(int i =0; i< library.length;i++) {
			System.out.println(library[i]);
		}
	}
}

출력 화면을 보면 각 인스턴스가 모두 잘 생성이 되었으며 내용물 또한 잘 출력됩니다. 그리고 각 배열 요소가 가지고 있는 인스턴스 주소 값까지 잘 출력되는 것을 볼 수 있습니다.

 

배열 복사하기

기존 배열과 자료형 및 배열 크기가 똑같은 배열을 새로 만들거나 배열의 모든 요소에 자료가 꽉 차서 더 큰 배열을 만들어야 할 때가 있습니다. 또한 기존의 배열에 저장된 자료를 가져오려고 할 때 이때 배열의 복사가 필요합니다.

배열을 복사하는 방법은 2가지입니다.

  1. 기존 배열과 배열 길이가 같거나 더 긴 배열을 만들고 for문을 반복하여 각 요소 값을 반복해서 복사하는 방법
  2. System.arraycopy(src, srcPos, dest, destPos, length) 메서드를 이용하기

-src : 복사할 배열 이름
-srcPos : 복사할 배열의 첫 번째 위치
-dest : 복사해서 붙여 넣을 대상 배열 이름
-destPos : 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치
-length : src에서 dest로 자료를 복사할 요소 개수

예제

package array;

public class ArrayCopy {

	public static void main(String[] args) {
		int[ ] array1 = {10, 20, 30, 40, 50};
		int[ ] array2 = {1,2,3,4,5};
		
		System.arraycopy(array1, 0, array2, 1, 4);
		
		for(int i=0;i<array2.length;i++) {
			System.out.println(array2[i]);
		}
	}
}

System.arraycopy를 통해서 array1의 일부 값들을 array2에다가 옮기는 과정입니다. 이때 System.arraycopy를 타이핑하는 순간 자동 완성이 될 텐데 각 자리가 어떤 것을 의미하는지 파악을 한 후에 뒤에 숫자만 1과 4로 바꿔줍니다. 1의 의미는 array2에 붙여 넣을 위치를 의미하며 4의 의미는 array1에서 array2로 복사할 개수를 의미합니다.

때문에 출력 값은 1, 10,20,30,40 이렇게 나오게 됩니다.

얕은 복사(Shallow Copy)

객체 배열도 마찬가지로 복사해서 사용이 가능합니다. 간단한 String 클래스를 사용한 예제를 적어보았습니다.

package array;

public class ObjectCopy2 {

	public static void main(String[] args) {
		Book [] bookArray1 = new Book[3];
		Book [] bookArray2 = new Book[3];
		
		bookArray1[0] = new Book("태백산맥","조정래");
		bookArray1[1] = new Book("데미안","헤르만헤세");
		bookArray1[2] = new Book("어떻게 살 것인가","유시민");
		
		System.arraycopy(bookArray1, 0, bookArray2, 0, 3);
		
		for(int i =0; i<bookArray2.length;i++) {
			bookArray2[i].showBookInfo();
		}
		
		System.out.println("==== bookArray1 ====");
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		
		for(int i =0; i<bookArray1.length;i++) {
			bookArray1[i].showBookInfo();
		}
		
		
		System.out.println("==== bookArray2 =====");
		for(int i =0; i<bookArray2.length;i++) {
			bookArray2[i].showBookInfo();
		}
	}
}

bookArray1을 System.arraycopy를 통해서 bookArray2에다가 넣으면 동일한 data가 나오게 됩니다. 하지만 중요한 점은 bookArray1의 0번째 index에 위치한 값을 "나목", "박완서"라고 바꿨을 때 bookArray2의 0번째 index가 가리키는 위치 또한 바뀌게 됩니다.

즉 해당 복사는 주소를 복사하고 있기 때문에 값을 bookArray1과 bookArray2가 공유를 하고 있습니다. 즉 이와 같은 복사를 얕은 복사(Shallow Copy)라고 합니다.

 

* 만약 각각의 배열 값이 다른 인스턴스를 가리키게 하고 싶다면 어떻게 해야 할까요

깊은 복사 (Deep Copy)

package array;

public class ObjectCopy3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book[] bookArray1 = new Book[3];
		Book[] bookArray2 = new Book[3];
		
		bookArray1[0] = new Book("태백산맥","조정래");
		bookArray1[1] = new Book("데미안","헤르만 헤세");
		bookArray1[2] = new Book("어떻게 살것인가","유시민");
		
		bookArray2[0] = new Book();
		bookArray2[1] = new Book();
		bookArray2[2] = new Book();
		
		for(int i=0;i<bookArray1.length;i++) {
			bookArray2[i].setBookName(bookArray1[i].getBookName());
			bookArray2[i].setAuthor(bookArray1[i].getAuthor());
		}
		for(int i=0;i<bookArray2.length;i++) {
			bookArray2[i].showBookInfo();
		}
		
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		
		System.out.println(" book Array1 출력 ");
		for(int i=0;i<bookArray1.length;i++) {
			bookArray1[i].showBookInfo();
		}
		
		System.out.println(" book Array2 출력 ");
		for(int i=0;i<bookArray2.length;i++) {
			bookArray2[i].showBookInfo();
		}
	}
}

다음과 같이 인스턴스를 따로 관리하고 싶을 때 직접 인스턴스를 만들고 그 값을 복사하면 깊은 복사가 이뤄집니다. 때문에 예제를 실행하였을 때 bookArray1의 값을 바꿔도 bookArray2에 더 이상 영향을 미치지 않게 됩니다.

 

다차원 배열 

다차원 배열은 이차원 이상으로 구현된 배열을 의미합니다. 

선언 방법 
1. int[ ][ ] arr = new int [2][3];
2. int [ ][ ] arr {{1,2,3}, {4,5,6}};

기존의 이차원 배열과는 다르게 인덱스 연산자를 위한 괄호가 2개 들어갔으며 개수에 따라서 차원이 증가하게 됩니다. 그리고 1차원 배열 선언과 동일하게 new 및 자료형이 사용되었으며 배열의 사이즈가 얼마인지를 결정하는 숫자가 들어가거나 또는 2번째 선언처럼 직접적으로 구성 숫자들이 들어가게 되어서 배열 선언을 할 수 있습니다.

예제

package array;

public class TwoDimension {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][]arr = {{1,2,3},{4,5,6}};
		
		for(int i=0;i<arr.length;i++) {   // 여기서 arr.length를 의미하는 것은 행의 개수를 의미함 ( 2x3행렬에서 세로 2 길이를 의미함, 세로축의 길이 ) 
			for(int j=0;j<arr[i].length;j++) {
				System.out.println(arr[i][j]); // 여기서 arr.length[i]의 길이를 의미하는 것은 열의 길이를 의미함. ( 2x3 행렬에서 3을 의미함. 가로축의 길이 ) 
			}
			System.out.println();
		}
	}
}

 

* 나 혼자 코딩 숙제 
: 알파벳 소문자를 2 글자씩 13줄(13행 2열)로 출력하는 프로그램을 이차우 너 배열로 구성해보기 

package array;

public class Alphabet {

	public static void main(String[] args) {
		char[][] arr = new char[12][2];
		char start = 0;
		arr[0][0] = 97;
		
		for(int i=0; i<arr.length;i++) {
			for(int j=0; j<arr[i].length;j++) {
				arr[i][j] = (char) (arr[0][0] + start);
				start = (char) (start +1);
				System.out.print(arr[i][j]);
			}
			System.out.println();
		}
	}
}

 

예제 ( 이차원 배열의 길이 출력해보기 ) 

package array;

public class TwoDimension2 {

	public static void main(String[] args) {
		int[][]arr = new int[2][3];
		
		for(int i=0;i<arr.length;i++) { // 행 길이 이용
			for(int j=0;j<arr[i].length;j++) { // 열 길이 이용 
				System.out.println(arr[i][j]);
			}
			System.out.println();
		}
		System.out.println(arr.length); // 행 길이 출력
		System.out.println(arr[0].length);	// 열 길이 출력
	}
}

해당 예제에서는 이차원 배열을 선언만 하고 특정한 값을 넣어주지 않았기 때문에 모두 0으로 출력됩니다.
arr.length를 의미하는 숫자는 행의 길이를 의미하며 즉 세로축의 길이를 의미합니다. 그리고 arr [i]. length는 가로축의 길이, 즉 열의 길이를 의미하는데 arr[i]라는 특정 i번째 행을 가르키고 있으므로 그때의 길이는 곧 열의 길이이므로  arr[i].length는 정확하게는 특정 행의 열 개수를 의미합니다.

Reference : INTRODUCTION OF JAVA PROGRAMMING ( DO IT )

반응형

'프로그래밍 ( Programming ) > JAVA' 카테고리의 다른 글

[JAVA] 상속에서 클래스 생성과 형 변환  (0) 2021.06.26
[JAVA] 상속이란?  (0) 2021.06.26
[JAVA] ArrayList 란  (0) 2021.06.10
[JAVA] static 응용 - 싱글톤 패턴  (0) 2021.05.28

댓글