배열의 가장 큰 단점은 고정된 크기입니다. 물론 늘리거나 줄일 수는 있지만 이를 로직으로 처리하는 과정은 불편함이 동반합니다.
오늘은 고정된 크기 배열을 해결하는 동적 배열인 리스트(List)에 대해 정리해 보겠습니다.
리스트는 배열과 비슷하게 데이터를 순차적으로 저장하는 자료구조이지만, 생성할 때 크기를 미리 정하지 않아도 되는 동적 배열입니다. 프로그램 실행 중에 데이터가 추가되면 자동으로 크기가 늘어나고, 삭제되면 줄어드는 유연함을 가지고 있습니다.
C#에서 리스트를 사용하기 위해서는 상단에 System.Collections.Generic 네임스페이스를 반드시 추가해줘야 합니다. 선언 시에는 꺽쇠 기호 안에 리스트에 담을 데이터의 타입을 명시합니다.
using UnityEngine;
using System.Collections.Generic; // List 사용을 위해 필수
public class ListBasic : MonoBehaviour
{
void Start()
{
// 리스트 선언 및 생성
List<int> scoreList = new List<int>();
List<string> nameList = new List<string>();
// 생성과 동시에 초기화하는 경우
List<string> items = new List<string>() { "포션", "마나약" };
}
}
리스트는 데이터를 관리하기 위한 다양한 메서드를 제공합니다.
Add: 리스트의 맨 뒤에 새로운 데이터를 추가합니다.
[index]: 배열과 마찬가지로 대괄호와 인덱스 번호를 사용하여 특정 위치의 데이터에 접근하거나 수정합니다.
Count: 현재 리스트에 들어있는 데이터의 개수를 반환합니다. (배열의 Length와 같은 역할)
Remove(값): 리스트 안에서 특정 값을 찾아 삭제합니다. 값이 존재하여 삭제에 성공하면 true를 반환합니다.
RemoveAt(인덱스): 특정 위치(번호)에 있는 데이터를 삭제합니다. 삭제 후 뒤에 있던 데이터들이 앞으로 한 칸씩 당겨집니다.
List<string> inventory = new List<string>();
// 데이터 추가
inventory.Add("강철 검");
inventory.Add("나무 방패");
inventory.Add("회복 포션");
// 데이터 접근 및 개수 확인
int itemCount = inventory.Count; // 결과: 3
string firstItem = inventory[0]; // 결과: "강철 검"
// 데이터 삭제 (값으로 삭제)
inventory.Remove("나무 방패"); // "나무 방패"가 사라지고 "회복 포션"이 1번 인덱스로 당겨짐
// 데이터 삭제 (인덱스로 삭제)
inventory.RemoveAt(0); // 0번에 있던 "강철 검" 삭제
배열과 리스트는 모두 데이터를 일렬로 저장한다는 공통점이 있지만, 상황에 따라 선택 기준이 달라집니다.
가장 큰 차이점은 크기의 고정 여부입니다. 배열은 처음에 정한 크기를 바꿀 수 없으므로, 데이터의 개수가 변하지 않는 스테이지 정보나 고정된 테이블 데이터를 다룰 때 유리하며 성능 면에서도 리스트보다 약간 더 빠릅니다.
반면 리스트는 크기가 자유롭게 변하기 때문에, 게임 도중 아이템을 얻거나 버리는 인벤토리 시스템, 생성되고 파괴되는 몬스터 목록처럼 데이터의 변화가 잦은 경우에 필수적으로 사용됩니다. 다만 내부적으로 크기를 조절하는 과정에서 배열보다 메모리 사용량이나 연산 비용이 조금 더 발생할 수 있습니다.
<참고자료>

오늘은 동적 Array 리스트에 대해 배웠습니다.
이전에는 Array와 List의 차이를 모르고 무작정 List만 사용하였는데, 크기 고정 여부나 메모리 효율에 대해 배우면서 명확한 차이를 알 수 있는 시간이었습니다. 또한 이전에 진행한 Array의 한칸 당기기가 List에서는 자동으로 처리된다는 점에 있어서 List의 장점에 대해서 명확하게 이해할 수 있는 시간이었습니다.