본문 바로가기

Language/Java

[Java] 배열이란?

배열이란? 자료가 연속으로 나열된 자료구조로, 배열을 사용하면 자료형이 같은 자료 여러 개를 한 번에 관리할 수 있다.

배열을 사용하려면 먼저 배열을 선언해야 한다.

배열도 변수와 마찬가지로 자료형을 함께 선언한다.

 자료형 [ ] 배열 이름 = new 자료형 [개수];
 자료형 배열 이름[ ] = new 자료형 [개수];

 

배열을 이루는 각각의 자료를 배열 요소라 한다. 배열 요소는 자료형이 모두 같다.

 

int[] studentIDs = new int[10];  //int형 요소가 10개인 배열 선언

 

위 문장은 int형 요소가 10개인 배열을 선언한 것이다.

이렇게 선언했을 때 메모리 상태를 나타내면

 

 

 

배열 초기화하기

자바에서 배열을 선언하면 그와 동시에 각 요소의 값이 초기화된다.

배열의 자료형에 따라 정수는 0, 실수는 0.0, 객체 배열은 null로 초기화되며, 배열 선언과 동시에 특정 값으로도 초기화할 수 있다.

 

int[] studentIDs = new int[] {101, 102, 103};  //개수는 생략함

int[] studentIDs = new int[3] {101, 102, 103};  //오류 발생

int[] studentIDs = {101, 102, 103};  //new int[] 부분 생략 가능, int형 요소 3개인 배열 생성

int[] studentIDs;
studentIDs = new int[] {101, 102, 103}; //배열 자료형 먼저 선언후 초기화할 경우 new int[] 생략 불가

 

 

 

배열 사용하기

선언한 배열의 각 요소에 값을 넣을 때나 배열 요소에 있는 값을 가져올 때는 [ ](인덱스 연산자)를 사용한다.

 

studentIDs[0] = 10;  //배열의 첫번째 요소에 값 10 저장

 

배열 이름에 [ ]를 사용하는 것을 인덱스 연산이라 한다.

인덱스 연산자의 기능은 배열 요소가 저장된 메모리 위치를 찾아주는 역할이다.

배열 길이(처음에 선언한 배열 전체 요소 개수)가 n이라고 하면, 배열 순서는 0번부터 n-1번까지이다.

0번 요소를 배열의 첫 번째 요소라고 한다.

 

[실습] 배열 초기화하고 출력하기
package array;

public class ArrayTest {
	public static void main(String[] args) {
		int[] num = new int[] {1,2,3,4,5,6,7,8,9,10};
		
		for(int i = 0; i < num.length; i++) {
			System.out.println(num[i]);
		}
	}
}

 

자바의 배열은 배열 길이를 나타내는 length 속성을 가진다.

자바에서 배열 길이는 처음에 선언한 배열의 전체 요소 개수를 의미한다. 전체 길이를 알고 싶은 배열 이름 뒤에 도트( . ) 연산자를 붙이고 length 속성을 쓰면 배열 길이를 반환한다.

 

[실습] 배열 길이만큼 출력하기
package array;

public class ArrayTest2 {
	public static void main(String[] args) {
		double[] data = new double[5];
		
		data[0] = 10.0;
		data[1] = 20.0;
		data[2] = 30.0;
		
		for(int i = 0; i < data.length; i++) {
			System.out.println(data[i]);
		}
	}
}

 

[실습] 배열의 유효한 요소 값 출력하기
package array;

public class ArrayTest3 {
	public static void main(String[] args) {
		double[] data = new double[5];
		int size = 0;
		
		data[0] = 10.0; size++;
		data[1] = 20.0; size++;
		data[2] = 30.0; size++;
		
		for(int i = 0; i < size; i++) {
			System.out.println(data[i]);
		}
	}
}

 

 

[실습] 알파벳 문자와 아스키코드 값 출력하기
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 등 기본 자료형 배열과 사용 방법이 조금 다르다

 

[실습] 객체 배열 만들기 (1)
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);
	}
}

 

 

[실습] 객체 배열 만들기 (2)
package array;

public class BookArray {
	public static void main(String[] args) {
		Book[] library = new Book[5];
		
		for(int i = 0; i < library.length; i++) {
			System.out.println(library[i]);
		}
	}
}

 

 

[실습] 객체 배열 만들기 (3)
package array;

public class BookArray2 {
	public static void main(String[] args) {
		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]);
		}
	}
}

 

Book 인스턴스 멤버들과 Book 인스턴스를 저장한 메모리 공간 주소가 차례로 출력된다.

 

 

 

[실습] 객체 배열 만들어 활용하기 - 나 혼자 코딩
학생 클래스 Student를 만들고 멤버 변수로 studentID, name을 선언한다. showStudnetInfo() 메서드를 만들어 studentID와 name 값을 출력한다. 그리고 StudentArray 클래스에서 Student 3명의 배열을 만들고 Student를 생성하여 저장한 후 for문을 사용하여 Student 정보를 출력한다. 출력 결과가 다음과 같도록 Student와 StudentArray 클래스를 만들어 보세요.
package array;

public class Student {
	int studentID;
	String studentName;
	
	public Student(int studentID, String studentName) {
		this.studentID = studentID;
		this.studentName = studentName;
	}
	
	public void showStudentInfo() {
		System.out.println(studentID + ", " + studentName);
	}
}
package array;

public class StudentArray {
	public static void main(String[] args) {
		Student[] student = new Student[3];
		
		student[0] = new Student(1001, "James");
		student[1] = new Student(1002, "Tomas");
		student[2] = new Student(1003, "Edward");
		
		for(int i = 0; i < student.length; i++) {
			student[i].showStudentInfo();
		}
	}
}

 

 

 

배열 복사하기

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

배열을 복사하는 방법은 두 가지가 있다.

  1. 기존 배열과 배열 길이가 같거나 더 긴 배열을 만들고 for문을 사용하여 각 요소 값을 반복해서 복사하는 방법
  2. System.arraycopy() 메서드를 사용하는 방법
    매개변수 설명
    src 복사할 배열 이름
    srcPos 복사할 배열의 첫 번째 위치
    dest 복사해서 붙여 넣을 대상 배열 이름
    destPos 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치
    length src에서 dest로 자료를 복사할 요소 개수
  3. System.arraycopy(src, srcPos, dest, destPos, length)

 

[실습] System.arraycopy()로 배열 복사하기
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]);
		}
	}
}

 

array1 배열에서 array2 배열로 요소 값을 복사한다.

array1 배열의 요소 0번(첫 번째 요소)부터 4개를 복사해서 대상 배열 array2의 요소 1번(두 번째 요소)부터 붙여 넣는다.

출력 결과를 보면 array2 배열의 첫 번째 요소 값인 1을 제외하고 나머지 요소 값만 변경된 것을 알 수 있다.

 

그렇다면 객체 배열도 복사해서 사용할 수 있다.

 

[실습] 객체 배열 복사하기
package array;

public class ObjectCopy1 {
	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();
		}
	}
}

 

 

[실습] 객체 배열의 얕은 복사
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 배열 요소 값을 변경했는데 bookArray2 배열 요소 값도 변경된 것을 알 수 있다.

그 이유는 객체 배열의 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스 주소 값이기 때문.

즉, 객체 배열을 복사할 때 인스턴스를 따로 생성하는 게 아니라 기존 인스턴스의 주소 값만 복사한다.

결국 두 배열의 서로 다른 요소가 같은 인스턴스를 가리키고 있어 복사되는 배열의 인스턴스 값이 변경되면 두 배열 모두 영향을 받는다.

이처럼 복사를 주소 값만 복사한다고 해서 ‘얕은 복사(shallow copy)’라고 한다.

그렇다면 인스턴스 값만 복사하고 배열의 각 요소가 서로 다른 인스턴스를 가리키게 하려면 ‘깊은 복사(deep copy)’를 해야 한다. 깊은 복사는 인스턴스를 직접 만들고 그 값을 복사하는 것이다.

 

 

 

[실습] 객체 배열의 깊은 복사
package array;

public class ObjectCopy3 {
	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("어떻게 살 것인가", "유시민");
		
		bookArray2[0] = new Book();  //디폴트 생성자로 bookArray2 배열 인스턴스 생성
		bookArray2[1] = new Book();
		bookArray2[2] = new Book();
		
		//bookArray1 배열 요소를 bookArray2 배열 인스턴스에 복사
		for(int i = 0; i < bookArray1.length; i++) {
			bookArray2[i].setBookName(bookArray1[i].getBookName());
			bookArray2[i].setAuthor(bookArray1[i].getAuthor());
		}
		
		//bookArray2 배열 요소 값 출력
		for(int i = 0; i < bookArray2.length; i++) {
			bookArray2[i].showBookinfo();
		}
		
		//bookArray1 첫 번째 배열 요소 값 변경
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		
		System.out.println("===bookArray1===");
		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();
		}
	}
}

 

 

향상된 for문과 배열

자바 5부터 제공되는 향상된 for문(enhanced for loop)은 배열의 처음에서 끝까지 모든 요소를 참조할 때 사용하면 편리한 반복문이다.

향상된 for문은 따로 초기화와 종료 조건이 없기 때문에 모든 배열의 시작 요소부터 끝 요소까지 실행한다.

for(변수 : 배열) {
	반복 실행문;
}

 

 

[실습] 향상된 for문 사용하기
package array;

public class EnhancedForLoop {
	public static void main(String[] args) {
		String[] strArray = {"Java", "Android", "C", "JavaScript", "Python"};
		
		for(String lang : strArray) {
			System.out.println(lang);
		}
	}
}

'Language > Java' 카테고리의 다른 글

[Java] ArrayList 클래스 사용하기  (0) 2022.11.15
[Java] 다차원 배열  (0) 2022.11.12
[Java] static 응용 - 싱글톤 패턴  (0) 2022.11.03
[Java] 변수 유효 범위  (0) 2022.10.20
[Java] static 변수  (0) 2022.10.18