Yoon DevLog
article thumbnail
Published 2023. 2. 22. 22:46
[JAVA] 배열(Array) 총 정리 개발/JAVA

 

 

배열이란?

배열이란 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것이다.

여기서 중요한 것은 '같은 타입'이어야 한다는 것이다.

 

배열을 구성하는 각각의 값을 요소(element)라 하고, 위치를 가리키는 숫자를 인덱스(index)라 부른다.

 

 

배열의 선언과 생성

배열을 선언하는 방법은 원하는 타입의 변수를 선언하고 변수 또는 타입에 배열임을 의미하는 대괄호를 붙이면 된다.

int[] numberAry;  // 타입[] 변수이름;
int numberAry2[]; // 타입 변수이름[];

배열을 선언한 다음에는 배열을 생성해야한다. 배열을 선언하는 것은 배열을 다루기 위한 공간이 만들어질 뿐이고, 배열을 생성해야만 비로소 값을 저장할 수 있는 공간이 만들어지는 것이다! 

String[] msg;        //타입[] 변수이름;          -> 배열을 선언(배열을 다루기위한 참조변수 선언)
msg = new String[5]; //변수이름 = new 타입[길이]; -> 배열을 생성(실제 저장공간을 생성)

String[] msg2 = {"a","b","c"};  // 선언 + 초기화를 한번에 진행

String[] msg3 = new String[3];
msg[0] = "Hi";
msg[1] = "Good";
msg[2] = "Day";    // 각 공간에 값을 초기화

또한 선언과 초기화를 한번에 진행하거나, 각 공간에 하나씩 값을 초기화할 수 있다.

 

 

배열 출력

배열을 출력할 때 일반 문자열이나, 정수를 출력하 듯이 출력하면 값이 출력되지 않는다.

int[] num = {1, 2, 3, 4, 5};
System.out.println(num); // [I@53e25b76 배열의 주소값이 출력된다.

----------------------------------------------------------------

// for문을 통해 요소 값 출력
for(int i=0; i<num.length; i++){ // num.length는 배열의 길이를 의미한다. 즉 5가된다.
	System.out.println(num[i]); 
}

// Arrays.toString() 메서드 사용하여 바로 출력
System.out.println(Arrays.toString(num)); // [1,2,3,4,5]

 

 

위의 소스와 같이 반복문이나, Arrays.toString() 메서드를 이용하여 배열을 문자열 형식으로 출력할 수 있다.

 

 

배열 복사

배열은 한번 생성하면 그 길이를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 내용을 복사해야한다.

int[] arr = new int[5]
int[] tmp = new int[arr.length*2]; // arr배열보다 길이가 2배인 배열 생성

for(int i=0; i<arr.length; i++)
	tmp[i] = arr[i]; // arr[i]의 값을 tmp[i]에 저장
    
arr = tmp; // 참조변수 arr이 새로운 배열을 가리키게 한다.

위와 같이 for문을 이용하여 복사하는 방법이 있다. 허나 이러한 작업들은 꽤나 비용이 많이 들기 때문에 배열의 길이를 넉넉하게 잡아줘서 새로 배열을 생성해야하는 상황을 가능한 적게 발생하게끔 해야 한다. 그렇다고 처음부터 너무 크게 잡아버리면 메모리를 낭비하게 된다.

 

int[] arr = new int[5]
int[] tmp = new int[arr.length*2]; // arr배열보다 길이가 2배인 배열 생성

System.arraycopy(arr, 0, tmp, 0, arr.length); 
// arraycopy(복사할 배열, 복사를 시작할 배열의 위치, 붙여넣을 배열, 
// 복사된 배열값들이 붙여질 시작위치, 지정된 길이만큼 값이 복사); 

tmp = Arrays.copyOf(arr, arr.length);
// arr 배열을 arr.length만큼 tmp배열에 전체 복사

System.arraycopy() 메서드나 Arrays.copyOf()를 사용하면 좀 더 간편하고, 직관적으로 배열을 복사할 수 있다. 또한 for문보다 훨씬 효율적이다! 둘이 거의 동일하기에 Arrays.copyOf()를 실무에서 많이 사용하는 편이다.

 

 

배열 정렬

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

Arrays.sort(arr); // 따로 반환되지않고 arr배열 자체를 정렬시킨다.

Arrays.sort(arr,Collections.reverseOrder()); // 배열을 내림차순으로 정렬한다.

Arrays.sort(arr, 0,2); // 배열 인덱스 0,1에 해당하는 요소만 정렬한다.

배열을 정렬할 때는 Arrays.sort() 메서드를 이용해 배열을 정렬할 수 있다. 정렬한 배열을 리턴하는 것이 아니라, 자신의 배열을 정렬시킨다.

 

 

배열 비교

String[] a = {"A","B","C"};
String[] b = {"A","B","C"};

Arrays.equals(a,b); // a배열과 b배열의 같을 경우 true , 다를경우 false를 리턴한다.

배열을 비교할 때 for문을 사용하여 비교할수도 있지만, Arrays.equals() 메서드를 이용해 쉽게 비교할 수 있다.

 


 

 

다차원 배열이란?

기존에 다뤘던 배열은 1차원 배열인데, 2차원 이상의 배열을 다차원 배열이라 부른다. 

현업에서는 주로 2차원 배열까지 사용하게 된다.

 

 

2차원 배열 생성

int[][] score = new int[4][3]; // 2차원 배열을 선언한다.
score[0][0] = 10;  // 인덱스별 요소 값을 지정한다.
score[0][1] = 20;
...
score[3][0] = 10;
score[3][1] = 20;

------------------------

// 생성과 동시에 초기화하는 것도 가능하다.
int[][] arr2 = {
                  {10,20,30},
                  {10,20,30},
                  {10,20,30},
                  {10,20,30}
                };

2차원 배열을 선언하는 방법은 대괄호를 [][] 2번 사용하면 된다. 위에 소스를 참고해보자.

 

 

2차원 배열 출력

2차원 배열 출력도 for문을 이용해 출력이 가능하다. 하지만 차원이 한개 더 존재하기에 중첩 for문을 이용해야 한다.

int[][] arr = {
                  {10,20,30},
                  {40,50,60},
                  {70,80,90},
                  {100,200,300}
              };
                
for(int i = 0 ; i < arr.length ; i++) {	// 먼저 열 부분을 순회하고
    for(int j = 0 ; j < arr[i].length ; j++) { // 행 부분을 순회하며 각 원소를 출력
        System.out.print(arr[i][j]);
    }
}

 

중첩 for문을 사용할 경우 수없이 많은 for문이 작동하게 된다. 이러면 성능에 영향을 끼치게 되는데, 중첩 for문 보다는 Arrays.deeptoString() 메서드를 이용해 2차원 배열을 한번에 출력할 수 있다.

int[][] arr = {
                  {10,20,30},
                  {40,50,60},
                  {70,80,90},
                  {100,200,300}
              };
                
System.out.println(Arrays.deepToString(arr)); 
 // [[10, 20, 30], [40, 50, 60], [70, 80, 90], [100, 200, 300]] 출력

 

 

2차원 배열 비교

2차원 배열 비교할때도 출력과 동일하게, 기존 메서드에서 depp을 붙여주면 된다. 즉, Arrays.deepEquals() 메서드를 사용하면 된다.

String[][] a = {
				{"A","B","C"},
                {"D","E","F"}
                };
String[][] b = {
				{"A","B","C"},
                {"D","E","F"}
                };

Arrays.deepEquals(a,b); // a배열과 b배열의 같을 경우 true , 다를경우 false를 리턴한다.

 

 


 

 

가변 배열이란?

자바에서는 2차원 이상의 배열을 '배열의 배열' 형태로 처리한다는 사실을 이용하면 보다 자유로운 형태의 배열을 구성할 수 있다.

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

int[][] score = {
	{100, 100, 100, 100},
    {20, 20, 20},
    {30, 30},
    {40, 40},
    {50, 50, 50}
}

자바의 정석 p.219

 

 

객체 배열이란?

객체 역시 배열로 다루는 것이 가능하고 이를 '객체 배열'이라고 한다.

객체 배열 안에 객체가 저장되는 것은 아니고, 객체의 주소가 저장된다. 즉, 객체 배열은 참조변수들을 하나로 묶은 참조변수 배열인 것이다.

 

Tv tv1, tv2, tv3;  ->  Tv[] tvArr = new Tv[3];

---------------------------------------------

tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();  // 객체를 생성해서 객체 배열의 각 요소에 저장

길이가 3인 객체 배열 tvArr을 생성하면, 각 요소는 참조변수의 기본 값인 null로 자동 초기화 된다. 그리고 이 객체 배열은 3개의 객체,

정확히는 객체의 주소를 저장할 수 있다.

 

객체 배열을 생성하는 것은, 그저 객체를 다루기 위한 참조변수들이 만들어진 것일 뿐, 아직 객체가 저장되지 않았다!

객체를 생성해서 객체 배열의 각 요소에 꼭 저장을 해줘야한다.

 

 

객체 배열 복사

객체로 이루어진 배열을 Arrays.copyOf / Arrays.copyOfRange 메서드를 통하여 배열을 복사할 경우 

객체 배열 요소에 저장된 값은 인스턴스 자체가 아닌 인스턴스의 주소 값을 가지고 있다. 즉, 두 배열의 다른 요소가 같은 인스턴스를 가리키고 있기에 복사한 배열의 인스턴스 값이 변경되면 모두 영향을 끼친다! 이를얕은 복사라 한다.

 

https://velog.io/@harinnnnn

그럼 깊은 복사(기존 배열에 영향을안끼치는 복사)를 하려면 어떻게해야하나?

번거롭지만 어쩔 수 없이 for문을 이용해서 복사하는 수 밖에 없다.

 

public class Test {
	public static void main(String[] args) {
		Phone[] phoneAry1 = new Phone[3];
		Phone[] phoneAry2 = new Phone[3];
		
		phoneAry1[0] = new Phone("아이폰");
		phoneAry1[1] = new Phone("삼성");
		phoneAry1[2] = new Phone("엘지");		
		phoneAry2[0] = new Phone();
		phoneAry2[1] = new Phone();
		phoneAry2[2] = new Phone();
		
		for(int i = 0; i<phoneAry1.length; i++) { // for문을 이용한 깊은복사
			phoneAry2[i].setPhoneName(phoneAry1[i].getPhoneName()); 
		} 		
	}
}

 

 


#참고자료

자바의 정석(남궁성 지음)

 

☕Java 객체 배열의 깊은 복사, 얕은 복사, 향상된 for문

객체 배열의 깊은 복사, 얕은 복사, 향상된 for문에 대해 알아봅니다.

velog.io

 

 

[JAVA] ☕ 자바 배열(Array) 문법 & 응용 정리

배열 자료형 배열(array)은 프로그래밍에서 필수로 등장하는 요소이며 정말 자주 쓰이는 자료형이다. 배열은 하나의 블록안에 여러 데이터들을 모아 집합시켜 저장함으로써 데이터를 구조적으로

inpa.tistory.com

 

profile

Yoon DevLog

@usnooy._.

백엔드 개발자 성장일기 -