공공부하자개발 · 영어 학습 노트
자바
초급자바의 뼈대0/8 완료
  • 00개발 환경과 첫 프로그램
  • 01변수, 데이터 타입, 형변환
  • 02연산자와 제어문
  • 031차원 · 2차원 배열
  • 04클래스, 객체, 생성자, 오버로딩
  • 05접근 제어자와 캡슐화
  • 06메서드 활용 패턴 (초급)
  • 07enum, 패키지와 import, static 과 final
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 초급 › 03 / 8

1차원 · 2차원 배열

섹션 7진행 0 / 8
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

3. 코드 예제

예제 1: 성적표 — 1차원 배열 통계

학생 점수 배열에서 합계·평균·최고·최저를 구하고 정렬해 상위 3명을 뽑습니다. Arrays.sort가 원본을 바꾸므로 복사본을 정렬합니다.

java
import java.util.Arrays;

public class GradeReport {
    public static void main(String[] args) {
        String[] names = {"김민수", "이서연", "박지훈", "최유진", "정우진"};
        int[] scores = {78, 92, 65, 88, 95};

        int sum = 0, max = scores[0], min = scores[0], maxIdx = 0;
        for (int i = 0; i < scores.length; i++) {
            sum += scores[i];
            if (scores[i] > max) { max = scores[i]; maxIdx = i; }
            if (scores[i] < min) min = scores[i];
        }
        System.out.printf("평균 %.1f / 최고 %d(%s) / 최저 %d%n",
                (double) sum / scores.length, max, names[maxIdx], min);
        // 출력: 평균 83.6 / 최고 95(정우진) / 최저 65

        int[] sorted = scores.clone();          // 원본 보존
        Arrays.sort(sorted);                    // 오름차순
        System.out.println("원본: " + Arrays.toString(scores));
        System.out.println("정렬: " + Arrays.toString(sorted));
        // 출력: 원본: [78, 92, 65, 88, 95]
        // 출력: 정렬: [65, 78, 88, 92, 95]

        System.out.print("상위 3점: ");
        for (int i = sorted.length - 1; i >= sorted.length - 3; i--) {
            System.out.print(sorted[i] + " ");
        }
        System.out.println();
        // 출력: 상위 3점: 95 92 88

        // 80점 이상 명단: 인덱스로 두 배열 연결
        int passCount = 0;
        for (int i = 0; i < scores.length; i++) {
            if (scores[i] >= 80) passCount++;
        }
        String[] passed = new String[passCount];
        int k = 0;
        for (int i = 0; i < scores.length; i++) {
            if (scores[i] >= 80) passed[k++] = names[i];
        }
        System.out.println("80점 이상: " + Arrays.toString(passed));
        // 출력: 80점 이상: [이서연, 최유진, 정우진]
    }
}

예제 2: 행렬 연산 — 2차원 정방 배열

행렬 덧셈과 곱셈, 전치를 구현합니다. 곱셈은 3중 반복문이며 A[i][k] * B[k][j]의 인덱스 구조를 익히는 것이 핵심입니다.

java
import java.util.Arrays;

public class MatrixOps {
    static int[][] add(int[][] a, int[][] b) {
        int rows = a.length, cols = a[0].length;
        int[][] r = new int[rows][cols];
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                r[i][j] = a[i][j] + b[i][j];
        return r;
    }

    static int[][] multiply(int[][] a, int[][] b) {
        int n = a.length, m = b[0].length, k = b.length;
        int[][] r = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                for (int x = 0; x < k; x++)
                    r[i][j] += a[i][x] * b[x][j];
        return r;
    }

    static int[][] transpose(int[][] a) {
        int[][] t = new int[a[0].length][a.length];
        for (int i = 0; i < a.length; i++)
            for (int j = 0; j < a[0].length; j++)
                t[j][i] = a[i][j];
        return t;
    }

    public static void main(String[] args) {
        int[][] a = {{1, 2}, {3, 4}};
        int[][] b = {{5, 6}, {7, 8}};

        System.out.println(Arrays.deepToString(add(a, b)));
        // 출력: [[6, 8], [10, 12]]
        System.out.println(Arrays.deepToString(multiply(a, b)));
        // 출력: [[19, 22], [43, 50]]
        System.out.println(Arrays.deepToString(transpose(new int[][]{{1, 2, 3}, {4, 5, 6}})));
        // 출력: [[1, 4], [2, 5], [3, 6]]

        // 행별 출력
        for (int[] row : multiply(a, b)) {
            for (int v : row) System.out.printf("%4d", v);
            System.out.println();
        }
        // 출력:   19  22
        // 출력:   43  50
    }
}

예제 3: 좌석 배치 — boolean 2차원 배열과 예약 로직

영화관 좌석을 boolean 배열로 관리합니다. 예약, 취소, 빈 좌석 수, 연속 빈 좌석 찾기를 구현합니다.

java
public class SeatMap {
    static final int ROWS = 4, COLS = 6;
    static boolean[][] seats = new boolean[ROWS][COLS];   // 기본값 false = 빈 좌석

    static boolean reserve(int r, int c) {
        if (r < 0 || r >= ROWS || c < 0 || c >= COLS) {
            System.out.println("잘못된 좌석: " + r + "," + c);
            return false;
        }
        if (seats[r][c]) {
            System.out.println("이미 예약됨: " + (char) ('A' + r) + (c + 1));
            return false;
        }
        seats[r][c] = true;
        return true;
    }

    static int countEmpty() {
        int n = 0;
        for (boolean[] row : seats)
            for (boolean taken : row)
                if (!taken) n++;
        return n;
    }

    // 같은 행에 k개 연속 빈 좌석의 시작 위치 찾기. 없으면 null
    static int[] findConsecutive(int k) {
        for (int r = 0; r < ROWS; r++) {
            int run = 0;
            for (int c = 0; c < COLS; c++) {
                run = seats[r][c] ? 0 : run + 1;
                if (run == k) return new int[]{r, c - k + 1};
            }
        }
        return null;
    }

    static void print() {
        for (int r = 0; r < ROWS; r++) {
            System.out.print((char) ('A' + r) + " ");
            for (int c = 0; c < COLS; c++) System.out.print(seats[r][c] ? "X " : "O ");
            System.out.println();
        }
    }

    public static void main(String[] args) {
        reserve(0, 0); reserve(0, 1); reserve(1, 3);
        reserve(0, 0);          // 출력: 이미 예약됨: A1
        reserve(9, 9);          // 출력: 잘못된 좌석: 9,9
        print();
        // 출력: A X X O O O O
        // 출력: B O O O X O O
        // 출력: C O O O O O O
        // 출력: D O O O O O O
        System.out.println("빈 좌석: " + countEmpty());          // 출력: 빈 좌석: 21
        int[] pos = findConsecutive(4);
        System.out.println("4연석 시작: " + (char) ('A' + pos[0]) + (pos[1] + 1));
        // 출력: 4연석 시작: A3
    }
}

예제 4: 얕은 복사 vs 깊은 복사

원시 배열, 2차원 배열, 객체 배열에서 복사가 어떻게 다른지 직접 확인합니다.

java
import java.util.Arrays;

public class CopyDemo {
    public static void main(String[] args) {
        // 1. 원시 타입 1차원: clone은 완전 독립
        int[] a = {1, 2, 3};
        int[] b = a.clone();
        b[0] = 99;
        System.out.println(a[0] + " " + b[0]);          // 출력: 1 99

        // 2. 대입은 복사가 아님
        int[] c = a;
        c[0] = 77;
        System.out.println(a[0]);                       // 출력: 77

        // 3. 2차원: clone은 얕은 복사
        int[][] m = {{1, 2}, {3, 4}};
        int[][] shallow = m.clone();
        shallow[0][0] = 99;
        System.out.println(m[0][0]);                    // 출력: 99  (안쪽 공유)
        System.out.println(m[0] == shallow[0]);         // 출력: true

        // 4. 깊은 복사
        int[][] deep = new int[m.length][];
        for (int i = 0; i < m.length; i++) deep[i] = m[i].clone();
        deep[1][1] = -1;
        System.out.println(Arrays.deepToString(m));     // 출력: [[99, 2], [3, 4]]
        System.out.println(Arrays.deepToString(deep));  // 출력: [[99, 2], [3, -1]]

        // 5. copyOf로 확장 — ArrayList가 내부적으로 하는 일
        int[] grown = Arrays.copyOf(a, 5);
        System.out.println(Arrays.toString(grown));     // 출력: [77, 2, 3, 0, 0]

        // 6. System.arraycopy: 기존 배열 일부에 덮어쓰기
        int[] dst = new int[6];
        Arrays.fill(dst, -1);
        System.arraycopy(a, 0, dst, 2, 3);              // a[0..3) → dst[2..5)
        System.out.println(Arrays.toString(dst));       // 출력: [-1, -1, 77, 2, 3, -1]

        // 7. 내용 비교
        System.out.println(a == a.clone());             // 출력: false
        System.out.println(Arrays.equals(a, a.clone())); // 출력: true
    }
}

예제 5: 가변 배열과 가변 인자 — 월별 매출 집계

분기마다 월 수가 다르다고 가정한 가변 배열과, 임의 개수 인자를 받는 varargs를 함께 씁니다.

java
import java.util.Arrays;

public class SalesReport {
    static long total(long... amounts) {          // 가변 인자 → long[]
        long s = 0;
        for (long a : amounts) s += a;
        return s;
    }

    public static void main(String[] args) {
        // 부서별 매출: 부서마다 지점 수가 다름 (가변 배열)
        long[][] sales = new long[3][];
        sales[0] = new long[]{1_200_000, 980_000};                       // 부서 0: 지점 2개
        sales[1] = new long[]{2_100_000, 1_750_000, 1_900_000, 800_000}; // 부서 1: 지점 4개
        sales[2] = new long[]{3_300_000};                                // 부서 2: 지점 1개

        long grand = 0;
        for (int d = 0; d < sales.length; d++) {
            long deptTotal = total(sales[d]);      // 배열을 varargs에 그대로 전달
            grand += deptTotal;
            System.out.printf("부서 %d (%d개 지점): %,d원%n", d, sales[d].length, deptTotal);
        }
        System.out.printf("총합: %,d원%n", grand);
        // 출력: 부서 0 (2개 지점): 2,180,000원
        // 출력: 부서 1 (4개 지점): 6,550,000원
        // 출력: 부서 2 (1개 지점): 3,300,000원
        // 출력: 총합: 12,030,000원

        System.out.println(total());                    // 출력: 0
        System.out.println(total(10, 20, 30));          // 출력: 60
        System.out.println(Arrays.deepToString(sales));
        // 출력: [[1200000, 980000], [2100000, 1750000, 1900000, 800000], [3300000]]
    }
}

예제 직접 실행

아래 폴더를 JDK 21 로 컴파일하고 실행합니다.

cd java-src\beginner\03_arrays
javac -encoding UTF-8 *.java && java Main
코드 예제
  • 예제 1: 성적표 — 1차원 배열 통계
  • 예제 2: 행렬 연산 — 2차원 정방 배열
  • 예제 3: 좌석 배치 — boolean 2차원 배열과 예약 로직
  • 예제 4: 얕은 복사 vs 깊은 복사
  • 예제 5: 가변 배열과 가변 인자 — 월별 매출 집계
이전 섹션2 핵심 원리3 / 7다음 섹션4 응용 변형 예제