본문 바로가기
Java

[Java] 배열

by lmyourpearl 2025. 11. 4.

배열은 같은 타입의 데이터를 연속된 공간에 나열하고, 각 데이터에 인덱스(index)를 부여해 놓은 자료구조이다.

int sum = 0;
for(int i=0; i<30; i++){
	sum += score[i];
}
int avg = sum / 30;

인덱스는 0부터 시작하며 for문이 30번 반복 실행하면서 i가 0~29까지 변하고 있음.

따라서 sum 변수에는 score[0]~score[29]까지 더해지고, 마지막으로 얻은 sum을 30으로 나누어 평균 avg를 얻음.


배열의 특징

1. 배열은 같은 타입의 데이터만 저장할 수 있음.

    int 배열은 int값만 저장 가능하고, String 배열은 문자열만 저장할 수 있으며, 선언과 동시에 저장할 수 있는 타입이 결정됨.

 

2. 한번 생성된 배열은 길이를 늘이거나 줄일 수 없음.


배열 선언

배열을 사용하기 위해서는 우선 배열 변수를 선언해야 하며, 배열 변수 선언은 두 가지 형식으로 작성할 수 있다.

// 형식 1
// 타입[] 변수;

int[] intArray;
double[] doubleArray;
String[] strArray;
// 형식 2
// 타입 변수[];

int intArray[];
double doubleArray[];
String strArray[];

 

배열 변수는 참조 변수에 속하며, 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 됨.

만일 참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화될 수 있음.

만약 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생함.

배열을 생성하고 배열 변수가 참조하는 상태에서 값을 저장하거나 읽어야 함.


배열 생성

배열 객체를 생성하려면 값 목록을 이요하거나 new 연산자를 이용하는 방법이 있음.

 

값 목록으로 배열 생성

// 값 목록으로 배열 생성
// 타입[] 변수 = {값0, 값1, 값2, 값3...};

String[] names = {"홍길동", "이몽룡", "변사또"};

 

값의 목록이 있다면 중괄호 { }는 주어진 값들을 항목으로 가지는 배열 객체를 힙에 생성하고, 배열 객체의 번지를 리턴하며 배열 변수는 리턴된 번지를 저장함으로써 참조가 이루어짐.

이렇게 생성된 배열에서 "홍길동"은 names[0], "이몽룡"은 names[1], "변사또"는 names[2]로 읽을 수 있으며 "홍길동"을 "홍준영"으로 바꾸고 싶다면 names[1] = "홍준영" 과 같이 대입 연산자를 사용하면 됨.

 

// 값 목록으로 배열 생성

package sec02.exam01;

public class ArrayCreateByValueListExample1 {
	public static void main(String[]args) {
    	int[] scores = {83,90,87};
        
        System.out.println("scores[0] : " + scores[0]);
        System.out.println("scores[1] : " + scores[1]);
        System.out.println("scores[2] : " + scores[2]);
        
        int sum = 0;
        for(int i=o; i<3; i++) {
          sum += scores[i];
        }
        System.out.println("총합 : " + sum);
        double avg = (double) sum / 3;
        System.out.println("평균 : " + avg);
     }
  }
  
// 실행 결과
// scores[0] : 83
// scores[1] : 90
// scores[2] : 87
// 총합 : 260
// 평균 : 86.66666666666667

* 값의 목록으로 배열 객체를 생성할 때는 배열 변수를 이미 선언한 후에는 다른 실행문에서 중괄호를 사용한 배열 생성이 허용되지 않는다는 점을 주의해야 함.

 

배열 변수를 미리 선언한 후 값 목록들이 나중에 결정되는 상황이라면 new 연산자를 사용해서 값 목록을 지정해주면 되는데, new 연산자 바로 뒤에는 배열 변수 선언에서 사용한 "타입[]"를 붙여주고 중괄호 { }에는 값들을 나열해줌.

// 변수 = new 타입[] {값1, 값2, 값3,...};

String[] names = null;
names = new String[] {"홍길동", "이몽룡", "변사또"};

메소드이 매개값이 배열일 경우에도 마찬가지로, 만약 매개 변수로 int[] 배열이 선언된 add()라는 메소드가 있을 경우, 값 목록을 배열로 생성함과 동시에 add()메소드의 매개값으로 사용하고자 할 때는 반드시 new 연산자를 사용해야함.

// 값 목록으로 배열 생성

package sec02.exam02;

public class ArrayCreateByValueListExample2 {
	public static void main(String[]args) {
      int[] scores;
      scores = new int[]{83,90,87};
      int sum1 = 0;
      for(int i=0; i<3; i++) {
        sum1 += scores[i];
      }
      System.out.println("총합 : " + sum1);
      
      
      int sum2 = add( new int[] {83,90,87} );
      System.out.println("총합 : " + sum2);
      System.out.println();
    }
    
    public static int add(int[]scores) {
      int sum = 0;
      for(int i=0; i<3; i++) {
        sum += scores[i];
      }
      return sum;
   }
}

// 실행 결과
// 총합 : 260
// 총합 : 260

new 연산자로 배열 생성

값의 목록을 가지고 있지 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면 new연산자로 객체 배열을 생성할 수 있으며, 길이는 배열이 저장할 수 있는 값의 개수를 말한다. 이미 배열 변수가 선언된 경우에도 new 연산자로 배열을 생성할 수 있음.

// new 연산자로 배열 생성

// 타입[] 변수 = new 타입[길이];

// 타입[] 변수 = null;
// 변수 = new 타입[길이];

int[] intArray = new int[5];
int[] scores = new int[30];
String[] names = new String[30];

 * new 연산자로 배열을 처음 생성할 경우 배열은 자동적으로 기본값으로 초기화함.

 

타입별 배열의 초기 값

분류 타입 초기값
기본 타입(정수) byte[ ]
char[ ]
short[ ]
int[ ]
long[ ]
0
'\u0000'
0
0
0L
기본 타입(실수) float[ ]
double[ ]
0.0F
0.0
기본 타입(논리) boolean[ ] false
참조 타입 클래스 null
인터페이스[ ] null

 

배열이 생성되고 나서 특정 인덱스 위치에 새로운 값을 저장하려면 다음과 같이 대입 연산자를 사용.

변수[인덱스] = 값;

 

// new 연산자로 배열 생성

package sec02.exam03;

public class ArrayCreateByNewExample {
	public static void main(String[] args) { 
      int[] arr1 = new int[3];
      for(int i=0; i<3; i++) {
        System.out.println("arr1[" + i + "] : " + arr1[i]);
      }
      arr1[0] = 10;
      arr1[1] = 20;
      arr1[2] = 30;
      for(int i=0; i<3; i++) {
        System.out.println("arr1[" + i + "] : " + arr1[i]);
      }
      
      double[] arr2 = new double[3];
      for(int i=0; i<3; i++) {
        System.out.println("arr2[" + i + "] : " + arr2[i]);
      }
      arr2[0] = 0.1;
      arr2[1] = 0.2;
      arr2[2] = 0.3;
      for(int i=0; i<3; i++) {
        System.out.println("arr2[" + i + "] : " + arr2[i]);
      }
      
      String[] arr3 = new String[3];
      for(int i=0; i<3; i++) {
        System.out.println("arr3[" + i + "] : " + arr3[i]);
      }
      arr3[0] = "1월";
      arr2[1] = "2월";
      arr2[2] = "3월";
      for(int i=0; i<3; i++) {
        System.out.println("arr3[" + i + "] : " + arr3[i]);
      }
   }
}

 

배열 길이

배열의 길이란 배열에 자장할 수 있는 전체 항목의 개수를 말하며, 코드에서 배열의 길이를 얻으려면 배열 객체의 length 필드를 읽음.

참고로 필드는 객체 내부의 데이터를 말하며, 배열 length 필드를 읽기 위해서는 배열 변수에 도트(.) 연산자를 붙이고 length를 적어주면 됨.

// 배열 길이
// 배열 변수.length;

int[] intArray = {10,20,30};
int num = intArray.length;

*배열의 length필드는 for문을 상요해서 배열 전체를 루핑할 때 유용함.

 

// 배열의 length 필드

package sec02.exam04;

public class ArrayLengthExample {
	public static void main(String[]args) {
      int[] scores = {83,90,87};
      
      int sum = 0;
      for(int i=0; i<scores.length; i++) {
        sum += scores[i];
      }
      System.out.println("총합 : " + sum);
      
      double avg = (double)sum / scores.length;
      System.out.println("평균 : " + avg);
   }
}

// 실행 결과
// 총합 : 260
// 평균 : 86.66666666666667

다차원 배열

값들이 행과 열로서 구성된 배열을 2차원 배열이하고하며, 2차원 배열은 수학의 행렬을 떠올리면 되는데, 가로 인덱스와 세로 인덱스를 사용함. 자바는 2차원 배열을 중첩 배열 방식으로 구현함.

// 타입[][] 변수 = { {값1, 값2,...}, {값1, 값2...},...};

int[][] scores = { {95,80}, {92,96} };
int score = scores[0][0];
int score = scores[1],[1];

* 이런 형태의 배열에서 주의할 점은 배열의 정확한 길이를 알고 인덱스를 사용해야 한다는 것.

 

// 배열 속의 배열

package sec02.exam05;

public class ArrayInArrayExample {
	public static void main(String[] args) { 
    
      int[][] mathScores = new int[2][3];
      for(int i=0; i<mathScores.length; i++) {
        for(int k=0; k<mathScores[i].length; k++) {
          System.out.println("mathScores["+i+"]["+k+"]="
          				   +mathScores[i][k]);
        }
      }
      System.out.println();
      
      int[][] englishScores = new int[2][];
      englishScores[0] = new int[2];
      englishscores[1] = new int[3];
      for(int i=0; i<englishScores.length; i++) {
        for(int k=0; k<englishScores[i].length; k++) {
          System.out.println("englishScores["+i+"]["+k+"]="
          				   +englishScores[i][k]);
        }
      }
      System.out.println();
      
      int[][] javaScores = { {95,80}, {92,96,80} };
      for(int i=0; i<javaScores.length; i++) {
        for(int k=0; k<javaScores[i].length; k++) {
          System.out.println("javaScores["+i+"]["+k+"]="
          				   +javaScores[i][k]);
        }
      }
   }
}

// 실행 결과
// mathScores[0][0]=0
// mathScores[0][1]=0
// mathScores[0][2]=0
// mathScores[1][0]=0
// mathScores[1][1]=0
// mathScores[1][2]=0

// englishScores[0][0]=0
// englishScores[0][1]=0
// englishScores[1][0]=0
// englishScores[1][1]=0
// englishScores[1][2]=0

// javaScores[0][0]=95
// javaScores[0][1]=80
// javaScores[1][0]=92
// javaScores[1][1]=96
// javaScores[1][2]=80

객체를 참조하는 배열

기본차입 배열은 각 항목에 직접 값을 갖고 있지만, 참조 타입(클래스, 인터페이스) 배열은 각 항목에 객체의 번지를 가지고 있는데, 예를 들어 String은 클래스이므로 String [ ]배열은 각 항목에 문자열이 아니라, String 객체의 번지를 가지고 있음.

즉, String[ ]배열은 String 객체를 참조하게 됨.

// 객체를 참조하는 배열

package sec02.exam06;

package class ArrayReferenceObjectExample {
	public static void main(String[] args) {
    	String[] strArray = new String[3];
        strArray[0] = "Java";
        strArray[1] = "Java";
        strArray[2] = new String("Java");
        
        System.out.println( strArray[0] == strArray[1] );
        System.out.println( strArray[0] == strArray[2] );
        System.out.println( strArray[0].equals(strArray[2] );
     }
  }
  
// 실행 결과
// true
// false
// true

배열 복사

배열은 한 번 생성하면 크기를 변경할 수 없기 때문에 더 많은 저장 공간이 필요하다면 더 큰 배열을 새로 만들고 이전 배열로부터 항목 값들을 복사해야 함. 배열 간의 항목 값들을 복사하려면 for문을 사용하거나 System.arraycopy( )메소드를 사용함.

// for문으로 배열 복사

package sec02.exam07;

public class ArrayCopyByForExample {
	public static void main(String[] args) {
      int[] oldIntArray = {1, 2, 3};
      int[] newIntArray = mew int[5];
      
      for(int i=0; i<oldIntArray.length; i++) {
        newIntArray[i] = oldIntArray[i];
      }
      
      for(int i=0; i<newIntArray.length; i++) {
        System.out.print(newIntArray[i] + ", ");
     }
   }
 }

// 실행 결과
// 1,2,3,0,0,

* 복사되지 않은 항목은 int[] 배열의 기초 초기값 0이 그대로 유지됨.

 

// System.arraycopy()로 배열 복사

package sec02.exam08;

public class ArrayCopyExample {
	public static void main(String[] args) {
      String[] oldStrArray = {"java", "array", "copy" };
      String[] newStrArray = new String[5];
      
      System.arrycopy ( oldStrArray, 0, newStrArray, 0, oldStrArray.length);
      
      for(int i=0; i<newStrArray.length; i++) {
        System.out.print(newStrArray[i] + ",");
     }
   }
 }

// 실행 결과
// java, array, copy, null, null,

* 복사되지 않은 항목은 String[ ] 배열의 초기값 null이 그대로 유지됨.

 

System.arraycopy( )메소드 호출 방법

// System.arraycopy( Object src, int srcPos, Object dest, int destPos, int length );

System.arraycopy( arr1, 0, arr2, 0, arr1.length );

src 매개값은 원본 배열이고, srcPos는 원본 배열에서 복사할 항목의 시작 인덱스이며 dest 매개값은 새 배열이고, destPos는 새 배열에서 붙여넣을 시작 인덱스이다. 마지막으로 length는 복사할 개수.


향상된 for문

배열이나 컬렉션을 좀 더 쉽게 처리하기 위해 향상된 for문을 제공하는데, 향상된 for문은 반복 실행을 하기 위해 루프 카운터 변수와 증감식을 사용하지 않음. for문의 괄호( )에는 배열에서 꺼낸 항목을 저장할 변수 선언과 콜론(:) 그리고 배열을 나란히 작성하며, 배열 및 컬렉션

항목의 개수만큼 반복하고, 자동적으로 for문을 빠져나감.

// 향상된 for문

package sec02.exam09;

public class AdvancedForExample {
	public static void main(String[] args) {
      int[] scores = {95, 71, 84, 93, 87 };
      
      int sum = 0;
      for (int score : scores) {
        sum = sum + score;
      }
      System.out.println("점수 총합 = " + sum);
      
      double avg = (double) sum / scores.length;
      System.out.println("점수 평균 = " + avg);
   }
 }
 
// 실행 결과
// 점수 총합 = 430
// 점수 평균 = 86.0

* for문의 반복 횟수는 배열의 항목 수가 됨.


 

🔘 배열: 같은 타입의 데이터를 연속된 공간에 나열하고, 각 데이터에 인덱스(index)를 부여해 놓은 자료구조

 

🔘 인덱스: 배열 항목에 붙인 번호를 말하며, 0번부터 시작하여 0~(배열 길이 -1)까지 범위를 가짐.

 

🔘 배열 선언: 변수 선언과 비슷한데, 대괄호가 추가되어 타입[] 변수; 형태로 선언되며, int [] scores는 int 배열을 선언하고,

여기서 scores는 배열 변수라고 부름.

 

🔘 배열 생성: 배열을 생성하는 방법은 두 가지이며 하나는 {값 1, 값 2, 값 3...}처럼 값 목록으로 생성하는 방법이고,

다른 하나는 new 타입[길이]; 로 생성하는 방법이 있음.

 

🔘 배열 길이: 배열에 저장될 수 있는 항목(값)의 수를 말하며, 배열의 length 필드에 저장되어 있기 때문에 변수. length로

배열 길이를 읽을 수 있음.

 

🔘 다차원 배열: 배열 항목(값)이 또 다른 배열을 참조할 때 이것을 다차원 배열이라고 함.

다차원 배열의 선언과 생성 방법은 타입[][] 변수 = new 타입[길이 1][길이 2];이며, 변수. length는 1차원 배열의 길이 1이 되고,

변수[인덱스]. length는 해당 항목이 참조하는 2차원 배열의 길이 2를 뜻함. 

 

🔘 향상된 for문: for(타입 변수 : 배열){...}을 말하며, 향상된 for문은 반복 실행을 하기 위해 루프 카운터 변수와 증감식을 사용하지 않음.

배열의 항목 개수만큼 반복하고, 자동적으로 for문을 빠져나가며, 반복할 때마다 변수에는 배열에서 가져온 항목이 저장됨.

'Java' 카테고리의 다른 글

[Java] 클래스  (0) 2025.11.06
[Java] 열거 타입  (0) 2025.11.05
[Java] 참조 타입과 참조 변수  (0) 2025.11.03
[Java] 반복문: for문, while문, do-while문  (0) 2025.11.03
[Java] 조건문: if문, switch문  (0) 2025.11.02