1.1 배열(Array)이란?

같은 타입의 여러 변수를 하나의 묶음으로 다루는 것을 "배열"이라고 한다. 많은 양의 데이터를 저장하기 위해서, 그 데이터의 숫자만큼 변수를 선언해야 한다면 매우 혼란스러울 것이다. 
이런 경우에 배열을 사용하면 하나의 변수로 많은 양의 데이터를 손쉽게 다룰 수 있다. 

[참고]서로 다른 타입의 데이터를 하나로 묶어서 다루려면, 클래스를 정의해서 사용하면 된다. 

한 학급의 시험점수를 저장하고자 할 때가 배열을 사용하기 좋은 예이다. 만일 배열을 사용하지 않는다면 5명의 학생의 점수를 저장하기 위해서 아래와 같이 해야 할 것이다. 


int score1=0, score2=0, score3=0, score4=0, score5=0 ; 


하지만, 배열을 사용하면 다음과 같이 간단히 할 수 있다. 


int[] score = new int[5]; // 5개의 int 값을 저장할 수 있는 배열을 생성한다. 


 
[그림5-1] 메모리에 생성된 변수들과 배열 


1.2 배열의 선언

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





1.3 배열의 생성

배열을 선언한 다음에는 배열을 생성해야한다. 배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어지는 것 뿐이다. 배열을 생성해야만 비로소 데이터를 저장할 수 있는 공간이 만들어지는 것이다. 

배열을 생성하기 위해서는 new연산자를 사용하고 배열의 타입과 크기를 지정해 주어야 한다. 



int[] score;  // 배열을 선언한다.(생성된 배열을 다루는데 사용될 참조변수 선언) 
score = new int[5];  // 배열을 생성한다.(5개의 int값을 저장할 수 있는 공간생성) 


[참고] 위의 두 문장은int[] score = new int[5];와 같이 한 문장으로 줄여 쓸 수 있다. 

사실 배열도 객체이기 때문에 멤버변수와 메서드를 갖고 있으며, 이 중 멤버변수 length는 배열의 크기에 대한 정보를 담고 있다. 위의 예제코드에서 score의 크기가 5이므로 score.length의 값은 5가 된다. 
[참고] 배열은 한번 생성되면 크기를 변경할 수 없다. 

배열의 선언과 생성과정을 단계별로 그림과 함께 자세히 살펴보도록 하자. 

1. int[] score; 
int형 배열 참조변수 score를 선언한다. 데이터를 저장할 수 있는 공간은 아직 마련되지 않았다. 

 

2. score = new int[5]; 
new연산자에 의해서 메모리의 빈공간에 5개의 int형 데이터를 저장할 수 있는 공간이 마련된다. 

 

그리고 각 배열요소는 자동적으로 int의 기본값(default)인 0으로 초기화 된다. 



마지막으로 할당연산자(=)에 의해서 배열의 주소가 int형 배열 참조변수 score에 저장된다. 

 
[참고]배열이 주소 0x100번지에 생성되었다고 가정한 것이다. 


이번엔 참조변수 배열의 예를 들어보자. 



String[] name;             // String타입의 참조변수 배열을 선언한다. 
name = new String[3];       // String인스턴스의 참조변수를 담을 수 있는 배열을 생성한다. 



위의 두 문장을 수행한 결과를 그림으로 표현하면 다음과 같다. 3개의 String타입의 참조변수를 저장하기 위한 공간이 마련되고 참조변수의 기본값은 null이므로 각 배열요소의 값은 null로 초기화 된다. 

 <BR> 

참고로 변수의 타입에 따른 기본값은 다음과 같다. 

 
[표5-1] 타입에 따른 변수의 기본값 



1.4 배열의 초기화

배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 초기화를 해주지 않아도 되지만, 원하는 값으로 초기화 하기 위해서 다음과 같이 한다. 


int[] score = new int[5];      // 크기가 5인 int형 배열을 생성한다. 
score[0] = 100;                   // 각 요소에 직접 값을 저장한다. 
score[1] = 90; 
score[2] = 80; 
score[3] = 70; 
score[4] = 60; 


 

String[] name = new String[3]; 
name[0] = new String("Kim"); 
name[1] = new String("Park"); 
name[2] = new String("Yi"); 


 <BR> 

이처럼 배열의 각 요소를 하나씩 초기화하는 것은 좀 불편하다. 그래서 자바에서는 보다 간편한 초기화 방법들을 제공한다. 이 때 배열의 크기는 따로 지정해주지 않으며 주어진 값의 개수에 따라 크기가 결정된다. 



int[] score = { 100, 90, 80, 70, 60}; 
int[] score = new int[]{ 100, 90, 80, 70, 60}; 

String[] name = { new String("Kim"), new String("Park"), new String("Yi")}; 
String[] name = { "Kim""Park""Yi"}; 
String[] name = new String[]{ new String("Kim"), new String("Park"), new String("Yi")}; 


[참고]String은 클래스이므로 new연산자를 통해 인스턴스를 생성해야하지만, "Kim"과 같이 쌍따옴표를 사용해서 간략히 표현하는 것을 특별히 허용한다. 



1.4 배열의 활용

배열의 각 저장공간에 값을 저장하고 또는 저장된 값을 읽어오기 위해서는 배열 참조변수와 인덱스를 이용한다. 배열의 인덱스는 배열의 각 저장공간에 자동적으로 주어지는 일련 번호인데, 0부터 시작해서 1씩 증가하는 연속적인 값이다. 크기가 5인 배열에서는 index의 범위가 0~4까지 모두 5개가 된다. 
배열의 값을 읽거나 저장하기 위해서는 다음과 같이 배열 참조변수와 배열의 인덱스를 사용하면 된다. 


score[3] = 100;         // 배열 score의 4번째 요소에 100을 저장한다. 
int value = score[3]; // 배열 score의 4번째 요소에 저장된 값을 읽어서 value에 저장한다. 


배열을 다루는데 있어서 for문은 거의 필수적으로 사용된다. 이 때 for문의 조건식으로 배열의 크기를 
직접 적어주는 것보다 배열의 속성인 length를 사용하는 것이 더 견고한 코드를 만든다. 


int[] score = { 100, 90, 80, 70, 60, 50 }; 

for (int i=0; i < 6; i++) { 
          System.out.println(score[i]); 



위의 코드는 배열의 각 요소를 for문을 이용해서 출력하는 일을 한다. 여기서 score배열의 크기는 6이며 인덱스의 범위는 0~5이다. 
이 때 코드를 다음과 같이 변경하여 배열에 저장될 값을 하나 줄인다면, 배열의 크기가 5로 변경되었으므로 유효한 인덱스의 범위는 0~4가 된다. 


int[] score = { 100, 90, 80, 70, 60 }; 

for (int i=0; i < 6; i++) { 
          System.out.println(score[i]); 



배열의 크기가 변경되었으니 for문에 사용되는 조건의 범위도 변경해주어야 하는데, 만일 이 것을 잊고 실행한다면 for문은 배열의 유효한 인덱스 범위인 0~4를 넘어 0부터 5까지 반복하기 때문에 5번째 반복에서 ArrayIndexOutOfBoundsException이라는 예외(일종의 에러)가 발생하여 비정상적으로 종료될 것이다. 

그래서 이러한 경우에는 for문의 조건식에 배열의 크기를 직접 적어주는 것보다 배열의 멤버변수인 length를 사용하는 것이 좋다. 위의 for문을 length를 사용해서 변경하면 다음과 같다. 


for(int i=0; i < score.length; i++) { 
     System.out.println(score[i]); 



length는 배열의 크기가 변경됨에 따라 자동적으로 변경된 배열의 크기를 갖기 때문에, 배열의 처리에 사용되는 for문의 조건식을 일일이 변경해주지 않아도 된다. 
이처럼 배열의 크기를 직접 적어주는 것보다 배열의 멤버변수인 length를 사용하는 것이 더 편리하고 안전하다. 

[예제5-1] ArrayEx1.java

class ArrayEx1 

      public static void main(String[] args) 
      { 
            int sum =0;                         // 총점을 저장하기 위한 변수 
            float average = 0f;             // 평균을 저장하기 위한 변수 

            int[] score = {100, 88, 100, 100, 90}; 

            for (int i=0; i < score.length ; i++ ) { 
                  sum += score[i];       // 반복문을 이용해서 배열에 저장되어 있는 값들을 더한다. 
            } 
            average = sum / (float)score.length ; // 계산결과를 float로 얻기 위함. 

            System.out.println("총점 : " + sum); 
            System.out.println("평균 : " + average); 
      } 

[실행결과]
총점 : 478 
평균 : 95.6 

for문을 이용해서 배열에 저장된 값을 모두 더한 결과를 배열의 개수로 나누어서 평균을 구하는 예제이다. 평균을 구하기 위해 전체 합을 배열의 크기인 score.length로 나누었다.
이 때 int와 int간의 연산은 int를 결과로 얻기 때문에 정확한 평균값을 얻지 못하므로 score.length를 float로 변환하여 나눗셈을 하였다. 

[예제5-2] ArrayEx2.java

class ArrayEx2 

      public static void main(String[] args) 
      { 
            int[] number = new int[10]; 

            for (int i=0; i < number.length ; i++ ) { 
                  System.out.print(number[i] = i);       // 배열을 0부터 9의 숫자로 초기화한다. 
            } 
            System.out.println(); 

            for (int i=0; i < 100; i++ ) { 
                  int n = (int)(Math.random() * 10);       // 0~9중의 한 값을 임의로 얻는다. 
                  int temp = number[0]; // 배열의 첫 번째 값과 임의로 선택된 위치의 값과 바꾼다. 
                  number[0] = number[n]; 
                  number[n] = temp; 
            } 
            for (int i=0; i < number.length ; i++ ) { 
                  System.out.print(number[i]);             // 배열의 내용을 출력한다. 
            } 
      } 

[실행결과]
0123456789 
5827164930 

크기가 10인 배열을 생성하고 0~9의 숫자로 차례대로 초기화하여 출력한다. 그 다음 random메서드를 이용해서 배열의 임의의 위치에 있는 값과 배열의 첫 번째 값을 교환하는 일을 100번 반복한다. 
그리고 그 결과를 화면에 출력한다. 이 예제를 응용하면 카드게임에서 카드를 한 벌을 생성하여 초기화한 다음 카드를 섞는 것과 같은 일을 할 수 있을 것이다. 
[참고]random메서드를 이용했기 때문에 실행 할 때 마다 결과가 다를 수 있다. 

[예제5-3] ArrayEx3.java


class ArrayEx3 

      public static void main(String[] args) 
      { 
            int[] number = new int[10]; 

            for (int i=0; i < number.length ; i++ ) { 
                  System.out.print(number[i] = (int)(Math.random() * 10)); 
            } 
            System.out.println(); 

            for (int i=0; i < number.length ; i++ ) { 
                  boolean changed = false;       // 자리바꿈이 발생했는지를 체크한다. 
                  for (int j=0; j < number.length-1-i ; j++ ) { 
                        if(number[j] > number[j+1]) { // 옆의 값이 크면 서로 바꾼다. 
                              int temp = number[j]; 
                              number[j] = number[j+1]; 
                              number[j+1] = temp; 
                              changed = true;       // 자리바꿈이 발생했으므로 changed를 true로. 
                        } // end if 
                  } // end for j 
                  for(int k=0; k < number.length; k++)

                        System.out.print(number[k]);       // 매 반복마다 정렬된 결과를 출력한다. 
                  System.out.println(); 
                  if (!changed) break;       // 자리바꿈이 없으면 반복문을 벗어난다. 
            } // end for i 
      } 

[실행결과]
1344213843 
1342134438 
1321344348 
1213343448 
1123334448 
1123334448 

크기가 10인 배열에 0과 9사이의 임의의 값으로 채운다음, 버블정렬 알고리즘을 통해서 크기순으로 정렬하는 예제이다. 이 알고리즘의 정렬방법은 아주 간단하다. 배열의 크기가 n일 때, 배열의 첫 번째부터 n-1까지의 요소에 대해, 근접한 값과 크기를 비교하여 자리바꿈을 반복하는 것이다. 
보다 효율적인 작업을 위해 changed라는 boolean형 변수를 두어서 자리바꿈이 없으면 break문을 수행하여 정렬을 마치도록 했다. 자리바꿈이 없다는 것은 정렬이 완료되었음을 뜻하기 때문이다. 
버블정렬은 다소 비효율적이긴 하지만 가장 간단한 정렬방법이다. 

[예제5-4] ArrayEx4.java

class ArrayEx4 

      public static void main(String[] args) 
      { 
            int[] number = new int[10]; 
            int[] counter = new int[10]; 

            for (int i=0; i < number.length ; i++ ) { 
                  System.out.print(number[i] = (int)(Math.random() * 10)); 
            } 
            System.out.println(); 

            for (int i=0; i < number.length ; i++ ) { 
                  counter[number[i]]++; 
            } 

            for (int i=0; i < number.length ; i++ ) { 
                  System.out.println( i +"의 개수 :"+ counter[i]); 
            } 
            
      } 

[실행결과]
4446579753 
0의 개수 :0 
1의 개수 :0 
2의 개수 :0 
3의 개수 :1 
4의 개수 :3 
5의 개수 :2 
6의 개수 :1 
7의 개수 :2 
8의 개수 :0 
9의 개수 :1 

이전 예제에서와 같이 크기가 10인 배열을 만들고 0과 9사이의 임의의 값으로 초기화 한다. 그리고 이 배열에 저장된 각 숫자가 몇번 반복해서 나타나는지를 세어서 배열 counter에 담은 다음 화면에 출력한다. 
[플래시동영상]자료실의 Array.swf을 보면 예제를 설명과 함께 순차적으로 실행과정을 볼수 있다.

[예제5-5] ArrayEx5.java

class ArrayEx5 

      public static void main(String[] args) 
      { 
            char[] hex = { 'C', 'A', 'F', 'E'}; 

            String[] binary = {"0000""0001""0010""0011" 
                                    , "0100""0101""0110""0111" 
                                    , "1000""1001""1010""1011" 
                                    , "1100""1101""1110""1111" }; 

            String result=""

            for (int i=0; i < hex.length ; i++ ) {             
                  if(hex[i] >='0' && hex[i] <='9') { 
                        result +=binary[hex[i]-'0'];       // '8'-'0'의 결과는 8이다. 
                  } else {       // A~F이면 
                        result +=binary[hex[i]-'A'+10]; // 'C'-'A'의 결과는 2 
                  } 
            } 
            System.out.println("hex:"new String(hex)); 
            System.out.println("binary:"+result); 
      } 

[실행결과]
hex:CAFE 
binary:1100101011111110 

16진수를 2진수로 변환하는 예제이다. 먼저 변환하고자 하는 16진수를 배열 hex에 나열한다. 16진수에는 A~F까지 6개의 문자가 포함되므로 char배열로 처리하였다. 그리고 String배열 binary는 이진수 0000 부터 1111(16진수로 0~F)까지 모두 16개의 값을 String으로 저장하였다. 
for문을 이용해서 배열 hex에 저장된 문자를 하나씩 읽어서 그에 해당하는 이진수 표현을 배열 binary에서 얻어 result에 덧붙이고 그 결과를 화면에 출력한다. 
[참고]16진수 1자리는 2진수 4자리에 해당된다. 16진수 A는 십진수로 10이고 B는 11이다. 

[예제5-6] ArrayEx6.java

class ArrayEx6 

      public static void main(String[] args) 
      { 
            String source = "SOSHELP"
            String[] morse = {".-""-...""-.-.","-..""." 
                                    ,"..-.""--.""....","..",".---" 
                                    , "-.-"".-..""--""-.""---" 
                                    , ".--.""--.-",".-.","...","-" 
                                    , "..-""...-"".--""-..-" 
                                    ,"-.--""--.." }; 
            String result=""

            for (int i=0; i < source.length() ; i++ ) { 
                  result+=morse[source.charAt(i)-'A']; 
            } 
            System.out.println("source:"+ source); 
            System.out.println("morse:"+result); 
      } 

[실행결과]
source:SOSHELP 
morse:...---.........-...--. 

문자열(String)을 모르스(morse)부호로 변환하는 예제이다. 이전의 16진수를 2진수로 변환하는 예제와 같지만, char배열 대신 이번엔 String을 사용했다. 
String의 문자의 개수는 length()를 통해서 얻을 수 있고, charAt(int i)메서드는 String의 i번째 문자를 반환한다. 그래서 for문의 조건식에 length()를 사용하고 charAt(int i)메서드를 통해서 source에서 한 문자씩 차례대로 읽어 올 수 있다. 

[참고]String클래스는 char배열을 내부 데이터로 갖으며 char배열을 다루는데 필요한 다양한 메서드를 제공한다. 




1.4 다차원 배열

자바에서는 1차원 배열 뿐만 아니라 2차원 이상의 다차원 배열도 허용한다. 그러나 특별한 경우를 제외하고는 2차원 이상의 배열은 잘 사용되지 않는다. 
그리고 2차원 배열을 잘 이해하면 2차원 이상의 배열에 응용하는 것은 그리 어렵지 않다. 본서에서는 2차원 배열에 대해서만 설명하도록 하겠다. 우선 2차원 배열의 선언방법은 다음과 같다. 

 

[참고]3차원이상의 고차원 배열의 선언은 대괄호[]의 개수를 차원 수 만큼 추가해 주기만 하면 된다. 

2차원 배열은 주로 테이블 형태의 데이터를 담는데 사용되며, 만일 5행 3열의 데이터를 담기 위한 배열을 생성하려면 다음과 같이한다. 


int[][] score = new int[5][3];      // 5행 3열의 2차원 배열을 생성한다. 


위 문장이 수행되면 score[0][0]부터 score[4][2]까지 15개의 저장공간이 마련된다. 

 

위와 같은 테이블형태의 데이터를 배열에 저장하기 위해서는 다음과 같이 한다. 


score[0][0]=100 ; 
score[0][1]=100 ; 
score[0][2]=100 ; 
score[1][0]=20 ; 
score[1][1]=20 ; 
... 
score[4][2]=50 ; 


1차원 배열에서와 같이 중괄호{}를 이용해서 2차원 배열의 생성과 초기화를 동시에 할 수도 있다. 


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


 

5행 3열의 2차원 배열을 생성하고 초기화한 결과를 그림으로 나타낸 것이다. 그림에서 알 수 있듯이 2차원 배열은 "배열의 배열"로 구성되어 있음을 알 수 있다. 즉, 여러 개의 배열이 모여서 또 하나의 배열을 이루고 있는 것이다. 
여기서 score.length의 값은 얼마일까? 배열 참조변수 score가 참조하고 있는 배열의 크기가 얼마인가를 세어보면 될 것이다. 그래서 score.length의 값은 5이다. score[0].length은 배열 참조변수 score[0]이 참조하고 있는 배열의 크기이므로 3이고 score[1].length, score[2].length, score[3].length, score[4].length의 값 역시 모두 3이라는 것을 쉽게 알 수 있을 것이다. 
만일 for문을 이용해서 2차원 배열을 초기화 한다면 다음과 같을 것이다. 


for (int i=0; i < score.length; i++) { 
     for (int j=0; j < score[i].length; j++) { 
           score[i][j] = 10; 
     } 




위의 코드는 2차원 배열 score의 모든 요소를 10으로 초기화 한다. 

[예제5-7] ArrayEx7.java

class ArrayEx7 

      public static void main(String[] args) 
      { 
            int[][] score = {{ 100, 100, 100} 
                                    , { 20, 20, 20} 
                                    , { 30, 30, 30} 
                                    , { 40, 40, 40} 
                                    , { 50, 50, 50}}; 
            int koreanTotal = 0; 
            int englishTotal = 0; 
            int mathTotal = 0; 

      System.out.println("번호 국어 영어 수학 총점 평균 "); 
      System.out.println("============================="); 

            for(int i=0;i < score.length;i++) { 
                  int sum=0; 
                  koreanTotal += score[i][0]; 
                  englishTotal += score[i][1]; 
                  mathTotal += score[i][2]; 
                  System.out.print(" " + (i + 1) + " "); 
                  for(int j=0;j < score[i].length;j++) { 
                        sum+=score[i][j]; 
                        System.out.print(score[i][j]+" "); 
                  } 
                  System.out.println(sum + " " + sum/(float)score[i].length); 
            } 
      System.out.println("============================="); 
      System.out.println("총점:" + koreanTotal + " " +englishTotal +" " +mathTotal); 
      } 

[실행결과]
번호 국어 영어 수학 총점 평균 
============================= 
1 100 100 100 300 100.0 
2 20 20 20 60 20.0 
3 30 30 30 90 30.0 
4 40 40 40 120 40.0 
5 50 50 50 150 50.0 
============================= 
총점:240 240 240 

5명의 학생의 세 과목 점수를 더해서 각 학생의 총점과 평균을 계산하고 과목별 총점을 계산하는 예제이다. 




1.7 가변 배열

자바에서는 2차원 이상의 배열에 대해서 "배열의 배열"의 형태로 처리한다는 사실을 이용하면 보다 자유로운 형태의 배열을 구성할 수 있다. 
2차원 이상의 다차원 배열을 생성할 때 전체 배열 차수 중 마지막 차수의 크기를 지정하지 않고, 추후에 각기 다른 크기의 배열을 생성함으로써 고정된 형태가 아닌 보다 유동적인 가변 배열을 구성할 수 있다. 
만일 다음과 같이 5 * 3크기의 2차원 배열 score를 생성하는 코드가 있을 때, 



int[][] score = new int[5][3]; 


위 코드를 다음과 같이 표현 할 수 있다. 



int[][] score = new int[5][];       // 두 번째 차원의 크기는 지정하지 않는다. 
score[0] = new int[3]; 
score[1] = new int[3]; 
score[2] = new int[3]; 
score[3] = new int[3]; 
score[4] = new int[3]; 


첫 번째 코드와 같이 2차원 배열을 생성하면 직사각형 테이블 형태의 고정적인 배열만 생성할 수 있지만, 두 번째 코드와 같이 2차원 배열을 생성하면 다음과 같이 각 열마다 다른 크기의 배열이 생성하는 것이 가능하다. 


int[][] score = new int[5][]; 
score[0] = new int[4]; 
score[1] = new int[3]; 
score[2] = new int[2]; 
score[3] = new int[2]; 
score[4] = new int[3]; 


위의 코드에 의해서 생성된 2차원 배열을 그림으로 표현하면 다음과 같다. 

 

score.length의 값은 여전히 5지만, 전과는 달리 score[0].length의 값은 4이고 score[1].length의 값은 3으로 서로 다르다. 
가변배열 역시 중괄호{}를 이용해서 다음과 같이 생성과 초기화를 동시에 하는 것이 가능하다. 


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


[플래시동영상]자료실의 MultiDim.swf을 보면 예제를 설명과 함께 순차적으로 실행과정을 볼수 있다.



1.8 배열의 복사

배열은 한번 생성하면 그 크기를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 내용을 복사해야한다. 
배열 간의 내용을 복사하려면 for문을 사용하거나 System클래스의 arraycopy메서드를 사용하면 된다. 예제를 통해서 배열을 복사하는 방법에 대해서 알아보도록 하자. 

[예제5-8] ArrayEx8.java

class ArrayEx8 

      public static void main(String[] args) 
      { 
            int[] number = {0,1,2,3,4,5}; 
            int[] newNumber = new int[10]; 
            
            for(int i=0; i < number.length;i++) { 
                  // 배열 number의 값을 newNumber에 저장한다. 
                  newNumber[i] = number[i];
            } 

            for(int i=0;i < newNumber.length;i++) { 
                  System.out.print(newNumber[i]); 
            } 
      } 

[실행결과]
0123450000 

더 큰 크기의 새로운 배열을 새로 만든 다음 이전 배열의 내용을 for문을 사용해서 복사하는 예제이다. 배열은 생성과 동시에 자동적으로 자신의 타입의 기본값으로 초기화 되므로 배열 newNumber의 요소들이 int의 기본값인 0으로 초기화 되었다는 것을 알 수 있다. 

System클래스의 arraycopy메서드를 사용하면 보다 간단히 배열을 복사할 수 있다. arraycopy메서드는 배열에 저장되어 있는 값만을 복사하기 때문에 참조변수 배열인 경우에는 단지 주소값만을 복사할 뿐 참조변수가 가리키고 있는 객체를 복사하지는 않는다. 
배열 abc와 number가 존재한다고 가정하고, abc의 내용을 number로 모두 복사하려면 다음과 같이 하면 된다. 


System.arraycopy(abc, 0, number, 0, abc.length);       


배열 abc의 내용을 배열 number로, 배열 abc에서 인덱스 0의 위치부터 시작해서 abc.length 만큼을 number의 인덱스 0인 위치에 복사한다. 
이때 복사하려는 배열의 위치가 적절하지 못하여 복사하려는 내용보다 여유공간이 적으면 ArrayIndexOutOfBoundsException이 발생한다. 

[예제5-9] ArrayEx9.java

class ArrayEx9 

      public static void main(String[] args) 
      { 
            char[] abc = { 'A', 'B', 'C', 'D'}; 
            char[] number = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 
            System.out.println(new String(abc)); 
            System.out.println(new String(number)); 

            // 배열 abc와 number를 붙여서 하나의 배열(result)로 만든다. 
            char[] result = new char[abc.length+number.length]; 
            System.arraycopy(abc, 0, result, 0, abc.length); 
            System.arraycopy(number, 0, result, abc.length, number.length); 
            System.out.println(new String(result)); 

            // 배열 abc을 배열 number의 첫 번째 위치부터 배열 abc의 크기만큼 복사 
            System.arraycopy(abc, 0, number, 0, abc.length);       
            System.out.println(new String(number)); 
            System.arraycopy(abc, 0, number, 6, 3);       // number의 인덱스6 위치에 3개를 복사 
            System.out.println(new String(number)); 
      } 

[실행결과]
ABCD 
0123456789 
ABCD0123456789 
ABCD456789 
ABCD45ABC9 




1.9 커맨드라인을 통해 입력받기

System.in.read()이외에 화면을 통해 사용자로부터 값을 입력받을 수 있는 간단한 방법이 있다. 바로 커맨드라인을 이용한 방법인데, 프로그램을 실행할 때 클래스이름 뒤에 공백문자로 구분하여 여러 개의 문자열을 프로그램에 전달 할 수 있다. 
만일 실행할 프로그램의 main메서드가 담긴 클래스의 이름이 MainTest라고 가정하면 다음과 같이 실행할 수 있을 것이다. 


c:\j2sdk1.4.1\work>java MainTest abc 123 

 

커맨드라인을 통해 입력된 두 문자열은 String 배열에 담겨서 MainTest클래스의 main메서드의 매개변수(args)에 전달된다. 그리고는 main메서드 내에서 args[0],args[1]과 같은 방식으로 커맨드라인으로 부터 전달받은 문자열에 접근할 수 있다. 여기서 args[0]는 "abc"이고 args[1]은 "123"이다.


 

[예제5-10] MainTest.java


class MainTest 

      public static void main(String[] args) 
      { 
            System.out.println("매개변수의 개수:"+args.length); 
            for(int i=0;i< args.length;i++) { 
                  System.out.println("args[" + i + "] = \""+ args[i] + "\"");

            } 

      } 

[실행결과]
C:\j2sdk1.4.1\work>java MainTest abc 123 "John Lim" 
매개변수의 개수:3 
args[0] = "abc" 
args[1] = "123" 
args[2] = "John Lim" 



커맨드라인에 입력된 매개변수는 공백문자로 구분하기 때문에 입력될 매개변수값에 공백이 있는 경우 겹따옴표(")로 감싸 주어야 한다. 그리고 커맨드라인에서 숫자를 입력해도 숫자가 아닌 문자열로 처리된다는 것에 주의해야한다. 

[예제5-11] MorseConverter.java

class MorseConverter 

      public static void main(String[] args) 
      { 
            if (args.length !=1) { 
                  System.out.println("usage: java MorseConverter WORD"); 
                  System.exit(0); 
            } 

            System.out.println("source:"+ args[0]); 
            String source = args[0].toUpperCase(); // 대문자로 변환한다. 
            
            String[] morse = {".-""-...""-.-.","-..""." 
                                    ,"..-.""--.""....","..",".---" 
                                    , "-.-"".-..""--""-.""---" 
                                    , ".--.""--.-",".-.","...","-" 
                                    , "..-""...-"".--""-..-" 
                                    ,"-.--""--.." }; 
            String result=""

            for (int i=0; i < source.length() ; i++ ) { 
                  result+=morse[source.charAt(i)-'A']; 
            } 
            
            System.out.println("morse:"+result); 
      } 

[실행결과]
C:\j2sdk1.4.1\work>java MorseConverter 
usage: java MorseConverter WORD 

C:\j2sdk1.4.1\work>java MorseConverter sos 
source:sos 
morse:...---... 

예제5-6을 변경하여 모르스부호로 변환할 문자열을 커맨드라인으로부터 입력받도록 변경하였다. 대문자만 변경 가능하도록 작성되어 있기 때문에 String클래스의 toUpperCase()를 이용해서 대문자로 변경한 다음에 모르스부호로 변환한다. 
그리고 실행 시 매개변수를 입력하지 않거나 둘 이상 입력하게 되면 사용법을 출력한다. 

[참고]커맨드라인에 매개변수를 입력하지 않으면 크기가 0인 배열이 생성되어 args.length의 값은 0이 된다. 이처럼 크기가 0인 배열을 생성하는 것도 가능하다.


출처 - http://cafe.naver.com/javachobostudy





'Development > JavaEssential' 카테고리의 다른 글

JRE (Java runtime environment)  (0) 2012.11.07
java - override  (0) 2012.11.03
java - 연산자 2  (1) 2012.10.07
java - 반복문  (0) 2012.10.03
java - 변수  (0) 2012.09.24
Posted by linuxism
,