새소식

JAVA

자바 기초 : 배열

  • -

핵심개념

  • 배열 : 같은 타입의 데이터를 연속된 공간에 나열하고 각 데이터에 인덱스를 부여한 자료구조이다. 인덱스는 배열 항목에 붙인 번호를 말하며 0부터 배열길이-1까지의 범위를 갖는다. 변수는 1개의 데이터만 저장할 수 있는데, 그렇기 때문에 많은 양의 데이터를 저장하려면 그만큼 많은 변수와 긴 코드가 필요하게 된다. 따라서 많은 양의 데이터를 손쉽게 처리할 수 있도록 배열이 사용된다. 배열은 아래와 같은 특징을 가진다.
    1. 같은 타입의 데이터만 저장할 수 있다.
    2. 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다.

  • 배열 선언 : 배열을 사용하기 위해서는 먼저 배열 변수를 선언해야 한다. 배열 변수 선언은 아래와 같이 2가지의 형식으로 작성할 수 있다. 여기서 타입은 배열에 저장될 데이터의 타입니다.
    형식 1 : 타입[]변수  int[] intArray;  -> intArray:배열변수
    형식 2 : 타입변수[] : int intArray;

    배열변수는 참조변수에 속하므로 배열도 객체이다. 만약 참조할 객체가 없다면 배열 변수는 null값으로 초기화될 수 있으며, 만약 배열 변수가 null값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하면 NullPointerException이 발생한다.

  • 배열 생성 : 배열 객체를 생성하려면 값 목록{값1, 값2,...}을 이용하거나 new 연산자를 이용한다.

  • 값 목록을 이용한 배열 생성 : 중괄호{}는 주어진 값들을 항목으로 가지는 배열 객체를 힙에 생성하고, 배열 객체의 번지를 리턴한다. 배열 변수는 리턴된 번지를 저장함으로써 참조가 이루어진다.
    ex) 타입[] 변수 = { 값1, 값2, ...};
    ex) String[] names { "김땡땡", "김자바"};  -> "김땡땡"은 names[0], "김자바"는 names[1]
          names[1] = "김파이"  -> 대입연산자를 사용하면 생성된 배열의 값을 바꿀 수 있음.
public static void main(String[] args) {
   int[]score = {81,82,83};
      System.out.println("score[0] : " + score[0]);
      System.out.println("score[1] : " + score[1]);
      System.out.println("score[2] : " + score[2]);

   int sum = 0;
      for (int i=0; i<3; i++) {
      sum += score[i];
   }
   System.out.println("총합:" +sum);
   double avg = (double) sum/3;
   System.out.println("평균:"+avg);
}
실행결과 : 
score[0] : 81
score[1] : 82
score[2] : 83
총합:246
평균:82.0

 

  • 배열 변수를 미리 선언한 후에는 다른 실행문에서 중괄호를 사용한 배열 생성이 허용되지 않는다. 만약 변수를 미리 선언한 뒤에 값 목록이 추후에 결정되는 상황이라면 new연산자를 사용해서 값 목록을 정해주어야 한다. 메소드의 매개값이 배열인 경우에도 마찬가지이다.
    ex)  int [] 변수;
    //변수 = {값0, 값1, ...}; -> 컴파일 에러
    변수 = new int[]{값0, 값1, ...);
    ex) int add(int[] score) {값0, 값2, ...};
        //int result = add ({90,91,92}); -> 컴파일 에러
          int result = add ( new int[]{90,91,92});
public static void main(String[] args) {
   int[]score;
// score={81,82,83} 오류발생.
   score = new int[] {81,82,83};
   int sum = 0;
      for (int i=0; i<3; i++) {
      sum += score[i];
      System.out.println("score{" + i + "]:" + score[i]);
   }
   System.out.println("총합:"+sum);

   int sum2 = add(new int[]{81,82,83});
      System.out.println("총합:"+sum2);
   }
   public static int add(int[]scores) {
   int sum = 0;
   for (int i=0;i<3;i++) {
      sum += scores[i];
   }
   return sum;
}

 

  • new연산자로 배열 생성 : 값의 목록을 가지고 있지는 않지만, 이후에 값들을 저장할 배열을 미리 만들어두고 싶다면 new 연산자로 다음과 같이 배열객체를 생성할 수 있다. 여기서 길이는 배열이 저장할 수 있는 값의 갯수이다. new연산자로 배열을 처음 생성할 경우 배열은 자동적으로 기본값으로 초기화되는데 예를들어 int는 0, String은 null값으로 초기화된다.
    ex) 타입[] 변수 = new 타입[길이];
분류 타입 초기값
기본타입(정수) byte[]
char[]
short[]
int[]
long[]
0
'\u0000'
0
0
0L
기본타입(실수) float[]
double[]
0.0F
0.0
기본타입(논리) boolean[] false
참조타입 클래스[]
인터페이스[]
null
null

 

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[] str3 = new String[3];
   for(int i=0; i<3; i++) {
      System.out.println("str3[" + i + "] : " + str3[i]);
   }
   str3[0] = "1월";
   str3[1] = "2월";
   str3[2] = "3월";
   for(int i=0; i<3; i++) {
      System.out.println("str3[" + i + "] : " + str3[i]);
}
}
실행결과 : 
arr1[0] : 0
arr1[1] : 0
arr1[2] : 0
arr1[0] : 10
arr1[1] : 20
arr1[2] : 30
arr2[0] : 0.0
arr2[1] : 0.0
arr2[2] : 0.0
arr2[0] : 0.1
arr2[1] : 0.2
arr2[2] : 0.3
str3[0] : null
str3[1] : null
str3[2] : null
str3[0] : 1월
str3[1] : 2월
str3[2] : 3월

 

  • 배열의 길이 : 배열에 저장할 수 있는 전체 항목의 개수이다. 변수.length로 배열 길이를 읽을 수 있다.
    ex) int[] int Array = {1,2,3};
          int num = intArray.lengh;
public static void main(String[] args) {
   int [] scores = {80, 85,90};
   System.out.println(scores.length);
   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);
}
실행결과 : 
3
총합 : 255
평균 : 85.0

 

  • main()메소드의 String[]args 매개변수 : 프로그램 실행을 위해서는 main()메소드가 필요하고 main()메소드의 매개값인 String[] args가 필요하다. main()메소드는 String[]args 매개 변수를 통해서 명령라인에서 입력된 데이터의수(배열의 길이)와 입력된 데이터(배열의 항몫값)을 알 수 있다. 만약 실행할 때 매개값을 주지 않았을 경우에는 길이가 0인 String배열을 생성한 뒤 main()메소드를 호출할 때 매개값으로 전달한다.
public static void main(String[] args) {
   System.out.println(args.length);
}
실행결과 : 0

 

  • 이클립스에서 매개값을 주는 방법
    1. Run -> Run Configuration 메뉴 선택
    2. Main탭에서 project와 Main class값 확인
    3. Arguments탭에서 Program arguments칸에 주고싶은 값 입력. ex) 문자열0 문자열1 문자열2
    4. Apply 버튼 클릭
    5. Ru 버튼 클릭
    결과 : args가 {문자열0, 문자열1, 문자열2} 배열을 참조하게 된다. 만약 산술 연산이 필요한 경우 문자열은 산술연산이 되지 않기 때문에 Integer.parseInt()메소드를 이용해서 정수로 변환하면된다.
public static void main(String[] args) {
   if(args.length!=2) {
      System.out.println("값의 수가 부족합니다.");
      System.exit(0); //강제종료
}

   String strNum1 = args[0]; //첫번째 데이터 얻기
   String strNum2 = args[1]; //두번째 데이터 얻기

   int num1 = Integer.parseInt(strNum1); //문자열을 정수로 변환하기
   int num2 = Integer.parseInt(strNum2);

   int result = num1 + num2;
   System.out.println(num1 + " + " + num2 + " = " + result);
}
실행결과 : 
이클립스에서 매개값을 주기 전 -> 값의 수가 부족합니다. (길이0인 String배열이 매개값으로 전달되기 때문)
이클립스에서 매개값 10 20을 준 후 -> 10 + 20 = 30

 

  • 다차원 배열 : 배열항목(값)이 또다른 배열을 참조할 때 이를 다차원 배열이라고 한다. 1차원 배열은 값 목록으로만 구성되어 있으며 2차원배열은 값들이 행과 열로 구성되어있다. 자바는 2차원 배열을 중첩 배열방식으로 구현한다. 다차원배열을 선언과 생성방법은 타입[][]변수 = new타입[길이1][길이2] 이다.
    ex) int[][]score = new int[2][3];      ->    2행 3열 (2차원 배열 길이를 3으로 같게 생성)
          scores.length; -> 2
          scores[0],length;  -> 3
          scores[1],length;  -> 3
(0,0) (0,1) (0,2)
(1,0) (1,1) (1,2)

 

       ex) int score = new int[2][ ];      ->    (2차원 배열 길이를 각각 다르게 생성)
             score[0] = new int[2];  -> 2
             score[1] = new int[3];  -> 3

 

       ex) int[ ][ ]scores = { {80,90}, {10,20} };

             int score = scores[0][0];  ->  95

             int score = scores[1][1];  ->  20

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[][] englisgScores = new int[2][ ];
   englisgScores[0] = new int[2]; // 0행에 0,1생성
   englisgScores[1] = new int[3]; // 1행에 0,1,2 생성
   for(int i=0; i<englisgScores.length; i++) {
      for(int k=0; k<englisgScores[i].length;k++) {
      System.out.println("englisgScores[" + i + "][" + k + "]=" + englisgScores[i][k]);
}
}
   System.out.println();

   int[][] javaScores = { {90,80}, {70,80,90} };
   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

englisgScores[0][0]=0
englisgScores[0][1]=0
englisgScores[1][0]=0
englisgScores[1][1]=0
englisgScores[1][2]=0

javaScores[0][0]=90
javaScores[0][1]=80
javaScores[1][0]=70
javaScores[1][1]=80
javaScores[1][2]=90

 

  • 객체를 참조하는 배열 : 참조타입(클래스, 인터페이스배열). 기본타입처럼 요소에 값을 직접 저장하지 않고 객체의 번지를 가지고 있다. 예를 들어 String은 클래스이므로 String[]배열은 각 항목에 문자열이 아닌 String 객체의 번지를 가지고 있으므로 String 객체를 참조하는 것이다.
    이때 String배열 항목 간의 객체의 번지를 비교할 때는 == 연산자를 사용하고, 항목간의 문자열을 비교하기 위해서는 equals() 메소드를 사용해야한다.
public static void main(String[] args) {
   String[] strArray = new String[3];
   strArray[0] = "A";
   strArray[1] = "A";
   strArray[2] = new String("A");

   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문을 이용해서 배열을 하나하나 복사
public static void main(String[] args) {
   int[] oldIntArray = {1,2,3};
   int[] newIntArray = new 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   //정수는 0으로 초기화되기때문에 복사되지 않은 부분은 0으로 출력됨.

 

  • System.arraycopy()메소드를 이용한 배열 복사 

      ex) 원본배열 arr1, 새배열 arr2인 경우
            System.arraycopy(arr1, 0, arr2, 0, arr1.length);

public class Ex09_ArrayCopy {
   public static void main(String[] args) {
   String[] oldStrArray = {"a", "b", "c"};
   String[] newStrArray = new String[5];

   System.arraycopy(oldStrArray, 0, newStrArray, 0, oldStrArray.length);

   for(int i=0; i<newStrArray.length;i++) {
      System.out.println(newStrArray[i] + " ");
}
}
실행결과 : a b c null null

 

  • 향상된 for문 : for(타입변수 : 배열){...} 형식이다. 배열이나 컬렉션을 좀 더 쉽게 처리할 수 있다. 향상된 for문의 특징은 반복실행을 위해서 루프카운터 변수나 증감식을 사용하지 않는다. 배열 값을 차례로 변수에 대입시키면서 배열 값의 갯수만큼 반복하고 for문을 빠져나가게된다. 반복할 때마다 변수에는 배열에서 가져온 항목이 저장된다.
public static void main(String[] args) {
   int[] scores = {95, 71, 84, 93, 87}; //배열값

   int sum = 0;
   for(int score : scores) {  //1.scores배열의 첫번째 값이 존재함.  2.해당 값을 score에 저장
   sum = sum + score//3.실행문 실행  4.다시 루프를 돌아 배열의 다음값이 존재하는지 평가 후 반복
} //5.더이상 가져올 값이 없으면 for문 종료
   System.out.println("점수 총합 = " + sum);

   double avg = (double)sum/scores.length;
   System.out.println("점수 평균 = " + avg);
}
실행결과 : 
점수 총합 = 430
점수 평균 = 86.0

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.