본문으로 건너뛰기
자료구조 · 알고리즘 기초집LESSON 03

배열과 ArrayList: 순서가 있는 게임 기록 관리

난이도초급 → 중급 입문
예상 시간40분
선수지식이전 강의

03강. 배열과 ArrayList: 순서가 있는 게임 기록 관리

1. 이번 강의에서 해결할 문제​

스테이지 수처럼 크기가 고정된 값과 플레이할 때마다 늘어나는 기록을 같은 구조에 넣으면 불필요한 복사나 빈 공간이 생깁니다.

2. 학습 목표​

3. 핵심 개념​

배열은 생성할 때 길이가 고정되고 원시 타입도 직접 저장합니다. ArrayList는 내부적으로 크기 조절 가능한 배열을 사용하지만, 용량 증가 방식은 API 계약과 구분해야 합니다. 둘 다 인덱스 접근은 O(1)입니다. 끝 추가는 ArrayList에서 평균적으로 amortized O(1)이지만 용량 확장 순간에는 복사가 필요합니다. 중간 삽입·삭제는 뒤 원소를 이동해 O(n)입니다.

먼저 알아야 할 용어​

용어뜻주의할 점
원소배열이나 목록에 들어 있는 값 하나이 예제에서는 목표 점수 또는 GameRecord 한 개입니다.
인덱스원소의 순서를 나타내는 0부터 시작하는 번호원소가 3개면 유효 인덱스는 0, 1, 2입니다.
길이·크기현재 사용할 수 있는 원소 수배열은 length, List는 size()로 확인합니다.
용량ArrayList 내부 배열이 재할당 없이 담을 수 있는 칸 수공개 API의 size()와 같은 뜻이 아닙니다.
amortized O(1)가끔 발생하는 큰 복사 비용을 여러 번의 끝 추가에 나누어 본 평균 비용매번 정확히 O(1)이라는 뜻은 아닙니다.

배열은 스테이지가 정확히 3개처럼 개수가 설계상 고정된 데이터에 알맞습니다. ArrayList는 플레이가 끝날 때마다 기록이 늘어나는 것처럼 실행 중 개수가 변하는 데이터에 알맞습니다. 어느 쪽이 더 최신 자료구조라서 고르는 것이 아니라, 크기 변경 요구에 따라 고릅니다.

4. 단계별 실습​

1. 예제 파일 작성​

실행 환경: 코드 편집기

실행 위치: C:\dev\game-ranking-algorithms

실행 전 확인: 같은 이름의 파일이 있다면 덮어쓰기 전에 Git diff로 변경 범위를 확인합니다. 선택한 LTS JDK의 java -version과 javac -version이 모두 실행되어야 합니다.

대상 파일: src/OrderedRecords.java

src/OrderedRecords.java
import java.util.ArrayList;
import java.util.List;

public class OrderedRecords {
record GameRecord(String playerId, int score) {}

public static void main(String[] args) {
int[] stageTargets = {500, 800, 1200};
List<GameRecord> records = new ArrayList<>();
records.add(new GameRecord("P1", 700));
records.add(new GameRecord("P2", 950));
records.add(1, new GameRecord("P3", 820));

System.out.println("2스테이지 목표: " + stageTargets[1]);
System.out.println("기록 순서: " + records);
}
}

코드 한 줄씩 이해하기​

  1. int[] stageTargets = {500, 800, 1200}은 길이 3인 정수 배열을 만듭니다. 두 번째 값의 인덱스는 1입니다.
  2. List<GameRecord> records는 코드를 구체 구현이 아닌 List 계약에 의존하게 합니다.
  3. 실제 객체는 new ArrayList<>()로 만들어 실행 중 기록을 추가할 수 있습니다.
  4. 두 번의 add(value)는 목록 끝에 P1과 P2를 넣습니다.
  5. add(1, P3)은 인덱스 1 자리를 비우려고 기존 P2를 뒤로 옮긴 뒤 P3를 넣습니다.
  6. 따라서 최종 순서는 P1, P3, P2이고, 원래 P2가 삭제된 것은 아닙니다.
실행 직후목록 상태
빈 ArrayList 생성[]
P1 추가[P1]
P2 추가[P1, P2]
인덱스 1에 P3 삽입[P1, P3, P2]

2. PowerShell에서 컴파일·실행​

실행 환경: Windows PowerShell

실행 위치: C:\dev\game-ranking-algorithms

실행 전 확인: src/OrderedRecords.java가 저장되었고 out 폴더에는 삭제해도 되는 컴파일 결과만 있는지 확인합니다.

대상: src/OrderedRecords.java와 out 아래 생성되는 class 파일

Windows PowerShell
Set-Location C:\dev\game-ranking-algorithms
New-Item -ItemType Directory -Force .\out | Out-Null
javac -Xlint:all -d .\out .\src\OrderedRecords.java
java -cp .\out OrderedRecords

예상 결과: record의 기본 문자열 표현에는 필드 이름도 포함됩니다. 핵심은 800과 P1 → P3 → P2 순서입니다.

2스테이지 목표: 800
기록 순서: [GameRecord[playerId=P1, score=700], GameRecord[playerId=P3, score=820], GameRecord[playerId=P2, score=950]]

실행 시간은 PC의 CPU·메모리, JDK 버전, JVM 워밍업, 백그라운드 작업과 입력 분포에 따라 달라질 수 있습니다. 측정값은 같은 조건에서 여러 번 비교하고 Big-O 분석과 함께 해석합니다.

5. 코드와 알고리즘이 동작하는 이유​

스테이지 목표는 개수가 고정되어 배열이 자연스럽습니다. 기록은 실행 중 늘어나므로 ArrayList가 크기 관리 책임을 맡습니다. add(1, value)는 인덱스 1 이후 원소를 한 칸씩 이동하기 때문에 O(n)이고, get(1)은 기준 주소에서 위치를 계산하므로 O(1)입니다.

6. 자주 하는 실수와 해결법​

7. 직접 실습​

실습 목표​

배열과 ArrayList에서 인덱스로 값을 읽고, 끝 추가와 중간 삽입의 결과 차이를 직접 확인합니다.

시작 전 상태​

OrderedRecords.java가 위 코드와 같고 P1, P3, P2 순서가 출력되어야 합니다. 각 변경 전에 예상 목록을 종이에 먼저 적습니다.

1단계: 가장 작은 변경 — 안전한 첫 값과 마지막 값​

records.get(0)으로 첫 기록을, records.get(records.size() - 1)로 마지막 기록을 출력합니다. 마지막 인덱스가 size() 자체가 아닌 size() - 1인 이유는 인덱스가 0부터 시작하기 때문입니다.

2단계: 값을 바꾸고 결과 비교​

records.add(new GameRecord("P4", 1100))로 끝에 추가한 결과와 records.add(1, ...)로 중간에 삽입한 결과를 비교합니다. 어느 기존 원소가 이동하는지 화살표로 그려 보세요.

3단계: 직접 적용 — 빈 목록도 안전한 출력​

새로운 빈 ArrayList<GameRecord>를 만들고, 비어 있으면 "기록 없음", 값이 있으면 첫 기록을 출력하는 조건을 작성합니다. 먼저 isEmpty()를 사용할 위치를 생각한 뒤 구현합니다.

4단계: 스스로 확인​

스테이지 목표 배열의 첫 값을 550으로 바꾸고 출력 변화를 확인합니다. 그다음 존재하지 않는 stageTargets[3]을 읽으면 왜 실패하는지, 유효 범위를 0 <= index < length로 설명합니다.

막혔을 때​

오류 또는 증상원인해결
ArrayIndexOutOfBoundsException배열의 인덱스가 0~length - 1 밖임접근 전 배열 길이와 인덱스를 출력합니다.
IndexOutOfBoundsException빈 List 또는 size() 위치를 읽음isEmpty()를 먼저 확인하고 마지막은 size() - 1로 계산합니다.
P2가 사라졌다고 생각함중간 삽입 뒤 출력 순서를 놓침삽입 전후 목록을 각각 출력해 P2가 뒤로 이동했는지 확인합니다.

실습 기록에는 입력 크기, 예상 결과, 실제 결과, 시간·공간 복잡도와 사용한 JDK 버전을 함께 남깁니다.

8. 이해 점검 질문 3개​

9. 핵심 요약​

다음 강의 연결​

다음 강의에서는 문자도 순서가 있는 자료라는 점을 이용해 문자열과 문자 배열의 순회·비교 흐름을 다룹니다.

MINI QUIZ

배열과 ArrayList: 순서가 있는 게임 기록 관리 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“배열과 ArrayList: 순서가 있는 게임 기록 관리” 내용을 실제 작업에 적용한 설명으로 가장 알맞은 것은 무엇인가요?
  2. 문제 2“배열과 ArrayList: 순서가 있는 게임 기록 관리” 실습 중 ‘배열의 마지막 유효 인덱스를 length로 사용하기’ 상황을 발견했습니다. 본문과 일치하는 설명은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

03강. 배열과 ArrayList: 순서가 있는 게임 기록 관리 미완료 상태