본문 바로가기

기술 서적/자바의 정석

[자바의 정석] ch5. 배열

>>배열

: 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것

 

배열의 선언

- 원하는 타입의 변수를 선언하고 대괄호[]를 붙임

- 배열의 선언 : 생성된 배열을 다루기 위한 참조변수를 위한 공간을 만들뿐

=> 배열의 생성을 해야 비로소 값을 저장할 공간이 만들어짐

 

 

ex)

int [] score;

//배열의 선언 -> 왼쪽 공간이 만들어짐

 

score= new int[5]

// 5개의 int 값을 저장할 수 있는 배열을 생성 -> 0x100에 5개의 int 공간 만들고 주소값을 score에 저장

 

 

>>배열의 index

: 배열의 요소마다 붙여진 일련번호

=> 인덱스를 벗어난 값을 사용하지 않도록 주의

=> 컴파일러가 범위 확인이 불가하므로 전적으로 프로그래머의 책임

 

# 배열의 길이는 0일 수도 있다.

 

ex)

public class Arrayex1 {
    public static void main(String[] args) {
        int [] score= new int[5];
        int k=1;
        for(int i=0; i<5; i++)
        {
            score[i]= 50+i*10;
        }
        int tmp= score[k+2]+score[4];

        for(int i=0; i<5; i++)
        {
            System.out.printf("score[%d] : %d%n", i, score[i]);
        }
        System.out.printf("tmp : %d%n", tmp);
        System.out.printf("score[%d] : %d%n", 7, score[7]); //범위를 넘은 값 반환
    }
}

 

 

>실행결과

score[0] : 50
score[1] : 60
score[2] : 70
score[3] : 80
score[4] : 90
tmp : 170
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 5
at Arrayex1.main(Arrayex1.java:16) => 인덱스의 유효한 범위를 넘음

 

 

>>배열의 길이(배열이름.length)

- 배열의 길이는 0일 수도 있다.

- 배열을 한번 생성하면 길이 변경이 불가하다.

 

>>배열의 초기화

- new 타입[]을 생략하여 코드를 간단히 할 수 있음

int [] score= new int[]{10,20,30,40,50} //OK
int [] score= {10,20,30,40,50}          //OK

 

but, 선언과 생성을 따로 하는 경우 new 타입[]을 생략 불가

int [] score;
score = new int[] {50,60,70,80,90}; //OK
score ={50,60,70,80,90}             //에러 -> new int[]를 생략 불가능

 

>>배열의 출력

Arrays.toString(arr) => 배열의 모든 요소를 "[첫번째, 두번째, ....]"같은 문자열로 반환

System.out.println(배열의 이름) => 타입 @내부주소

System.out.println(char 배열) -> 구분자 없이 이어서 출력

import java.util.*;

public class Arrayex3 {

    public static void main(String[] args) {
        int [] arr1= new int[10];
        int [] arr2 = new int[10];
        int [] arr3= new int[]{100,95,80,70,60};
        char [] charr= {'a', 'b', 'c', 'd'};

        for(int i=0; i<arr1.length; i++)
        {
            arr1[i]= i+1;
        }
        for(int i=0; i<arr2.length; i++)
        {
            arr2[i]= (int)(Math.random()*10)+1;
        }

        for(int i=0; i<arr1.length; i++)
        {
            System.out.print(arr1[i]+", ");
        }
        System.out.println();
        System.out.println(Arrays.toString(arr2));
        System.out.println(Arrays.toString(arr3));
        System.out.println(Arrays.toString(charr));
        System.out.println(arr3);  // int배열 출력 -> 타입@내부주소
        System.out.println(charr); //char 배열 출력-> 그대로 이어붙여짐


    }
}

>실행결과

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
[9, 10, 8, 9, 9, 1, 2, 7, 5, 10]
[100, 95, 80, 70, 60]
[a, b, c, d]
[I@6e8cf4c6
abcd

 

 

>>배열의 복사

- 더 많은 저장공간이 필요할 때: 더 큰 배열선언 ->복사

 

방법1. 길이 2배 배열 선언->for문을 활용해 옮김(비효율적)

ex)

public class arrayex4 {
    public static void main(String[] args) {
        int [] arr=new int[5]; //길이가 5인 배열 선언

        //배열 arr에 1-5저장
        for(int i=0; i<arr.length; i++)
        {
            arr[i]=i+1;
        }
        System.out.println("[변경 전]");
        System.out.println("arr.length: "+ arr.length);
        for(int i=0; i<arr.length; i++)
        {
            System.out.println("arr[" +i+"] : "+arr[i]);
        }
        //복사 과정
        //1단계 -> 길이가 확장된 배열 선언
        int [] tmp = new int[arr.length*2];

        //2단계 -> 값 옮기기
        for(int i=0; i<arr.length;i++)
        {
            tmp[i]= arr[i];
        }

        //참조변수 갱신
        arr= tmp;

        System.out.println("[변경 후]");
        System.out.println("arr.length: "+ arr.length);
        for(int i=0; i<arr.length; i++)
        {
            System.out.println("arr[" +i+"] : "+arr[i]);
        }

    }
}

>실행결과

[변경 전]
arr.length: 5
arr[0] : 1
arr[1] : 2
arr[2] : 3
arr[3] : 4
arr[4] : 5
[변경 후]
arr.length: 10
arr[0] : 1
arr[1] : 2
arr[2] : 3
arr[3] : 4
arr[4] : 5
arr[5] : 0
arr[6] : 0
arr[7] : 0
arr[8] : 0
arr[9] : 0

 

방법2. System.arraycopy() => 더 효율적

 

>>예제

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

        char [] result= new char [abc.length+num.length];
        System.arraycopy(abc, 0,result,0,abc.length);
        System.arraycopy(num, 0, result, abc.length, num.length);
        System.out.println(result);

        System.arraycopy(abc,0,num,0,abc.length);
        System.out.println(num);

        System.arraycopy(abc,0,num,6,abc.length);
        System.out.println(num);


    }
}

 

>>실행결과

ABCD
0123456789
ABCD0123456789
ABCD456789
ABCD45ABCD

 

>>배열의 활용

 

>총점과 평균 반환

public class Arrayex5 {

    public static void main(String[] args) {
        int sum=0;
        int []score= {100,88,100,100,90};
        float avg;
        for(int i=0; i<score.length; i++)
        {
            sum+=score[i];
        }
        avg= sum/(float)score.length;

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

    }
}

 

>>최대값과 최소값

public class Arrayex6 {
    public static void main(String[] args) {
        int [] score={79,88,91,33,100,55,95};

        int max=score[0];
        int min=score[0];

        for(int i=1; i<score.length; i++)
        {
            if (max<score[i])
            {
                max=score[i];
            }
            else if(min>score[i])
            {
                min=score[i];
            }

        }

        System.out.println("최대값 : "+max);
        System.out.println("최소값 : "+min);

    }
}

 

>> 섞기

public class Arrayex8 {
    public static void main(String[] args) {
        int [] ball= new int[45];
        int j=0;
        int tmp=0;

        for(int i=0; i<45; i++)
        {
            ball[i]= i+1;
        }

        for(int i=0;i<6; i++) {
            j = (int) (Math.random() * 45) + 1;
            tmp = ball[j];
            ball[i] = ball[j];
            ball[j] = tmp;
        }

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

 

>>버블정렬

public class bubblesort {

    public static void main(String[] args) {
        int[] numArr= new int[10];
        boolean change=false;
        int temp=0;

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

        for(int i=0; i<numArr.length-1; i++)
        {
            change=false;
            for(int j=0; j<numArr.length-1-i;j++)
            {
                if(numArr[j]> numArr[j+1])
                {
                    temp= numArr[j];
                    numArr[j]=numArr[j+1];
                    numArr[j+1]=temp;
                    change=true;
                }
            }

            if(!change)
            {
                break;
            }

            for(int k=0; k<numArr.length; k++)
            {
                System.out.print(numArr[k]);
            }
            System.out.println();
        }
    }
}

 

>>counter 만들기

import java.util.*;

public class Counter {

    public static void main(String[] args) {
        int [] num= new int[10];
        int [] counter = new int[10];
        int j;
        for(int i=0; i<num.length; i++)
        {
            j= (int)(Math.random()*10);
            counter[j]+=1;
            num[i]=j;
        }
        System.out.println(Arrays.toString(num));

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

    }
}

 

>>실행결과

[8, 8, 1, 9, 7, 9, 3, 2, 2, 8]
0의 개수 : 0
1의 개수 : 1
2의 개수 : 2
3의 개수 : 1
4의 개수 : 0
5의 개수 : 0
6의 개수 : 0
7의 개수 : 1
8의 개수 : 3
9의 개수 : 2

 

 


2. String 배열

 

String 배열의 선언과 생성

 

- String 배열은 참조배열임

String [] name = new String[3];
String [] name = new String [] {"Kim", "Park"};

=> 배열에 실제 객체가 아닌 객체의 주소가 저장되어 있음

=> default 값으로 null이 지정되어 있음

 

String class

-> char 배열에 여러가지 기능을 추가하여 확장한 것

- String 클래스는 char 배열에 기능을 추가한 것이다.

 

char배열과 String class의 차이

String 객체 : 읽기만 가능/ 내용변경 불가

 

String 클래스의 주요 메서드

메서드 설명
int length() 문자열의 길이 반환
char charAt(int idx) index에 있는 문자 반환
String substring(int from, int to) from-(to-1)에 있는 문자열 반환
bollean equals(Object obj) 두 문자열 내용이 같은지 확인
char [] toCharArray() 문자열을 문자배열(char[] 로 변환해서 반환)

 

2-4) 커맨드 라인을 통해 입력받기

- 사용자로부터 화면을 통해 값을 입력받음

- 여러개의 매개변수가 String 배열에 담겨 전달됨

- 매개변수가 입력되지 않을 수 있으므로 예외처리를 해주어야 함.


3. 다차원 배열

 

3-1) 2차원 배열의 선언과 인덱스

 

3-2) 2차원 배열의 초기화

=> 괄호를 한번 더 써서 초기화해준다.

 

=> 메모리에 저장되는 형태

 

score.length=15

score[0].length=3

 

3-3) 가변배열

- 2차원 이상의 배열을 배열의 배열로 처리함

 

3-4) 다차원 배열의 활용

- 좌표에 X표하기

 

public class HelloApplication {
    public static void main(String[] args) {
        final int SIZE=10;
        int x=0, y=0;

        char [] [] board=new char [SIZE][SIZE];
        byte[][] shipBoard={
                {0,0,0,0,0,0,1,0,0},
                {1,1,1,1,0,0,1,0,0},
                {0,0,0,0,0,0,1,0,0},
                {0,0,0,0,0,0,1,0,0},
                {0,0,0,0,0,0,0,0,0},
                {1,1,0,1,0,0,0,0,0},
                {0,0,0,1,0,0,0,0,0},
                {0,0,0,1,0,0,0,0,0},
                {0,0,0,0,0,1,1,1,0},
        };

        for(int i=0; i<SIZE; i++){
            board[0][i]= board[i][0]= (char)(i+'0');
        }
        Scanner scanner= new Scanner(System.in);

        while(true){
            System.out.println("좌표를 입력하세요. 종료는 00");
            String input= scanner.nextLine();

            if(input.length()==2){
                x= input.charAt(0)-'0';
                y= input.charAt(1)-'0';

                if(x==0 && y==0){
                    break;
                }
            }

            if(input.length()!=2 || x<=0 ||x>=SIZE||y<=0||y>=SIZE){
                System.out.println("잘못된 값을 입력하셨습니다.");
                continue;
            }

            board[x][y]=shipBoard[x-1][y-1]==1? 'O':'X';

            for(int i=0; i<SIZE; i++){
                System.out.println(board[i]);
            }
            System.out.println();
        }

    }
}

 

>>실행결과

좌표를 입력하세요. 종료는 00
13
0123456789
1  X      
2         
3         
4         
5         
6         
7         
8         
9         

좌표를 입력하세요. 종료는 00
17
0123456789
1  X   O  
2         
3         
4         
5         
6         
7         
8         
9         

좌표를 입력하세요. 종료는 00
00

 

- 빙고