[Java] 1-2. 배열

루키·2024년 7월 21일

Java

목록 보기
6/10
post-thumbnail

1. 배열이란?

동일한 타입의 데이터 2개 이상을 하나의 연속된 메모리 공간에서 관리하는 것을 배열이라고 합니다.

1-1. 1차원 배열 생성과 초기화

  • 배열의 선언 : 생성하고 싶은 변수의 타입과 [ ]기호를 통해 배열을 선언할 수 있습니다.

    • <타입>[ ] <변수명>; or <타입> <변수명>[ ];
    • Ex) int[ ] num_lst; String names[ ];
  • 배열의 생성 및 초기화 : new키워드를 사용해서 선언된 배열을 생성/초기화합니다.

    • new <타입>[<크기>];
    • Ex) num_lst = new int[5]; // int타입 자료형을 5개 저장할 수 있는 배열 생성
    • 배열을 초기화하면 해당 자료형의 기본값으로 default 초기화를 진행합니다.
    • 자료형기본값
      booleanfalse
      char'\u0000'
      byte,short,int0
      long0L
      float0.0f
      double0.0
      참조형 변수null
  • 배열의 생성과 동시에 할당한 값으로 초기화하기 : 생성과 동시에 값을 전달해주면 기본값이 아닌 원하는 값으로 할당하며 초기화할 수 있습니다. 단, 초기화는 생성할 때만 가능합니다. 이후에는 각 값을 따로 변경해줘야합니다.

    • int[] a = new int[] {1,2,3,4,5};
    • int[] b = {1,3,5,7,9};
    • int[] c; c = {2,4,6,8} // 컴파일 에러
  • 배열의 특징

    • 배열을 선언한 변수는 stack메모리에 저장되며 배열의 시작 주소만 담고 있습니다.
    • 실제 배열은 heap메모리에 저장되며 시작 주소를 기준으로 연속된 메모리에 저장됩니다.
    • 배열에 접근할 때는 index 번호를 가지고 각 요소에 접근할 수 있습니다. (index는 0부터 시작)
      • num_lst[1] = 1;
      • System.out.print(num_lst[1]); // 1
    • 배열을 간단하게 출력할 때는 Arrays.toString(<배열>)으로 확인 가능합니다.

1-2. 배열의 활용

  • 배열에서의 반복문
    가독성이 개선된 반복문으로 배열 및 Collections에서 사용할 수 있는 반복문입니다.
    index 대신 직접 요소(element)에 접근하는 변수를 제공합니다. 요소에 직접 접근하다보니 index를 사용할 수 없다는 특징이 있습니다.
//EX)
int[] num_lst = {1,2,3,4,5};
for(int n : num_lst) {
    System.out.println(n);
}
  • 배열의 수정 / 복사
    배열은 최초 메모리 할당 이후, 변경할 수 없다는 불변 객체(Immutable Object) 입니다.
    개별 요소는 다른 값으로 변경이 가능하나, 요소를 추가하거나 삭제, 배열의 크기 변경은 불가능합니다.

    배열을 복사할 때는 복사 method를 사용해서 복사할 수 있습니다.
    기본적으로 = 대입 연산자를 통해서 복사를 한다면 얕은 복사(Shallow Copy)가 일어나게 됩니다. 얕은 복사는 배열을 복사해서 새로 생성하는 것이 아닌, 원래 있는 배열의 주소값을 같이 갖게 되므로 원본 배열이 변경되면 얕은 복사를 한 배열도 같이 변경됩니다.
    깊은 복사(Deep Copy)를 해주면 이러한 문제를 해결할 수 있습니다. 배열을 복사해서 한 개 더 만들 때 사용하는 깊은 복사 method 2가지가 제공됩니다.

    • System.arrayCopy(Object src, int srcPos, Object dst, int dstPos, int length);

      • src: 원본 배열 / srcPos: 복사를 시작할 위치 / dst: 복사할 배열 / dstPos: 붙여넣을 위치 / length: 복사할 길이
      • 해당 메소드를 사용하기 위해서는 배열을 미리 생성 및 초기화까지 진행해야합니다.
      • 원본 배열의 크기나 복사 받을 배열의 크기가 length보다 작다면 오류가 발생합니다.
    • Arrays.copyOf(Object src, int length);

      • src: 원본 배열 / length: 복사할 길이
      • 해당 메소드는 return값으로 복사한 배열을 return합니다. 따라서 미리 배열을 생성/초기화 할 필요가 없습니다.
      • length가 원본 배열의 길이보다 크더라도 오류가 발생하지 않고 기본값으로 채워서 생성해줍니다.

2. 다차원 배열

2-1. 다차원 배열 생성

  • 2차원 배열의 선언 : 생성하고 싶은 변수의 타입과 [ ][ ]기호를 통해 배열을 선언할 수 있습니다.

    • <타입>[ ][ ] <변수명>; or <타입>[ ] <변수명>[ ]; or <타입> <변수명>[ ][ ]
    • Ex) int[ ][ ] num_lst; String[ ] names[ ]; boolean visited[ ][ ];
  • 2차원 배열의 생성 및 초기화 : new키워드를 사용해서 선언된 배열을 생성/초기화합니다.

    • new <타입>[<크기>][<크기>];
    • Ex) num_lst = new int[5][3]; // int타입 자료형을 3개 저장할 수 있는 배열을 담을 수 있는 배열을 5개 생성
  • 배열의 생성과 동시에 할당한 값으로 초기화하기 : 다차원 배열도 { }, 기호로 값을 할당하며 초기화 할 수 있습니다.

    • int[][] a = new int[] {{1,2},{3,4},{5,6}};
  • 다차원 배열은 꼭 같은 차원의 배열이 같은 크기일 필요는 없습니다. 2차원 이상의 배열에서는 하위 차원의 배열의 주소값만 갖게 되므로 크기가 모두 같지 않아도 됩니다.

    • EX)
      int[][] num_lst = new int[2];
      num_lst[0] = new int[3];
      num_lst[1] = new int[2];
      // num_lst 배열의 생성 결과
      // 0 0 0
      // 0 0

2-2. 다차원 배열 순회(탐색)

  • 2차원 배열 전체 탐색
// EX) 5*5 배열 순회하기
int N = 5;
int[][] board = new int[N][N];
/*배열 값 할당 완료되었다고 가정*/
for(int r = 0; r < N; r++) {
    for(int c = 0; c < N; c++) {
        System.out.print(board[r][c]);
        System.out.print(" ");
    }
    System.out.println();
}
// 위의 코드와 똑같이 동작함
for(int[] row : board) {
    for(int col: row) {
        System.out.print(col);
        System.out.print(" ");
    }
    System.out.println();
}
  • 2차원 배열에서 특정 위치의 상/하/좌/우 4방향 탐색
// EX) 5*5 배열에서 각 칸의 4방향의 합 출력하기
int[][] deltas = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int N = 5;
int[][] board = new int[N][N];
/*배열 값 할당 완료되었다고 가정*/
for(int r = 0; r < N; r++) {
    for(int c = 0; c < N; c++) {
        int sum = 0;
        for(int d = 0; d < 4; d++) {
            int nr = r + deltas[d][0];
            int nc = c + deltas[d][1];
            if(0 <= nr && nr < N && 0 <= nc && nc < N){
                sum += board[nr][nc];
            }
        }
        System.out.print(sum);
        System.out.print(" ");
    }
    System.out.println();
}
profile
주니어 FrontEnd 개발자가 되기 위한 기록

0개의 댓글