C#에서 동적 배열(dynamic array)은 크기를 동적으로 조정할 수 있는 배열을 의미한다. 기본적인 배열과는 달리, 동적 배열은 크기가 고정되어 있지 않아 필요에 따라 요소를 추가하거나 제거할 수 있다. 즉, 동적으로 조절 가능하다. C#에서는 List<T>가 대표적인 동적 배열의 예이다.
List<T>는 System.Collections.Generic 네임스페이스에 포함되어 있으며, 요소의 추가, 제거, 검색 등의 다양한 기능을 제공한다.
List<T>의 주요 메서드
- Add(T item): 리스트에 요소를 추가합니다.
- Remove(T item): 리스트에서 특정 요소를 제거합니다.
- RemoveAt(int index): 리스트의 특정 인덱스에 있는 요소를 제거합니다.
- Clear(): 리스트의 모든 요소를 제거합니다.
- Count: 리스트에 있는 요소의 개수를 반환합니다.
- Contains(T item): 리스트에 특정 요소가 포함되어 있는지 확인합니다.
- Insert(int index, T item): 리스트의 특정 인덱스에 요소를 삽입합니다
Unity Example로 보는 List
using System.Collections.Generic;
using UnityEngine;
public class ListExample : MonoBehaviour
{
// GameObject 타입의 리스트 선언
public List<GameObject> enemies;
void Start()
{
// 리스트 초기화
enemies = new List<GameObject>();
// Add: 요소 추가
for (int i = 0; i < 5; i++)
{
GameObject enemy = new GameObject("Enemy" + i);
enemies.Add(enemy);
Debug.Log("Added: " + enemy.name);
}
// Count: 리스트의 요소 개수
Debug.Log("Enemy Count: " + enemies.Count);
// Insert: 특정 인덱스에 요소 삽입
GameObject specialEnemy = new GameObject("SpecialEnemy");
enemies.Insert(2, specialEnemy); // 2번째 인덱스에 삽입
Debug.Log("Inserted: " + specialEnemy.name + " at index 2");
// Contains: 특정 요소가 리스트에 있는지 확인
if (enemies.Contains(specialEnemy))
{
Debug.Log("List contains: " + specialEnemy.name);
}
// Remove: 특정 요소 제거
enemies.Remove(specialEnemy);
Debug.Log("Removed: " + specialEnemy.name);
// RemoveAt: 특정 인덱스의 요소 제거
enemies.RemoveAt(0); // 첫 번째 요소 제거
Debug.Log("Removed element at index 0");
// Clear: 모든 요소 제거
enemies.Clear();
Debug.Log("Cleared all elements");
// 최종적으로 리스트의 요소 개수 확인
Debug.Log("Final Enemy Count: " + enemies.Count);
}
}
//예제 결과값
Added: Enemy0
Added: Enemy1
Added: Enemy2
Added: Enemy3
Added: Enemy4
Enemy Count: 5
Inserted: SpecialEnemy at index 2
List contains: SpecialEnemy
Removed: SpecialEnemy
Removed element at index 0
Cleared all elements
Final Enemy Count: 0
1. 적 캐릭터 추가
Add 메서드를 사용하여 리스트에 5개의 적 캐릭터가 추가되었다.
2.요소 개수 확인
Count 프로퍼티를 사용하여 리스트에 5개의 요소가 있는 것을 확인했다.
3. 특정 인덱스에 요소 삽입
Insert 메서드를 사용하여 리스트의 2번째 인덱스에 "SpecialEnemy"를 삽입했다.
4. 특정 요소 포함 여부 확인
Contains 메서드를 사용하여 리스트에 "SpecialEnemy"가 포함되어 있는 것을 확인했다.
5. 특정 요소 제거
Remove 메서드를 사용하여 리스트에서 SpecialEnemy를 제거했다.
이 때 리스트의 요소들이 자동으로 재정렬되어 빈 칸을 메꾼다. 즉, 리스트 내의 요소들은 인덱스에 맞게 다시 정렬된다.
6. 특정 인덱스의 요소 제거
RemoveAt 메서드를 사용하여 리스트의 첫 번째 요소(0번째 인덱스)를 제거했다.
7. 모든 요소 제거
Clear 메서드를 사용하여 리스트의 모든 요소를 제거했다.
8. 최종 요소 개수 확인
마지막으로 Count 프로퍼티를 사용해서 리스트에 남아 있는 요소가 0개임을 확인했다.
*주의사항
List<T>에서 Remove나 RemoveAt 메서드를 사용하여 요소를 제거하면, 리스트의 요소들이 자동으로 재정렬되어 빈 칸을 메꾼다. 즉, 리스트 내의 요소들은 인덱스에 맞게 다시 정렬된다.
Remove 와 RemoveAt 예제
using System.Collections.Generic;
using UnityEngine;
public class ListExample : MonoBehaviour
{
// GameObject 타입의 리스트 선언
public List<GameObject> enemies;
void Start()
{
// 리스트 초기화
enemies = new List<GameObject>();
// Add: 요소 추가
for (int i = 0; i < 5; i++)
{
GameObject enemy = new GameObject("Enemy" + i);
enemies.Add(enemy);
Debug.Log("Added: " + enemy.name);
}
// Count: 리스트의 요소 개수
Debug.Log("Enemy Count: " + enemies.Count);
// 가운데 요소 제거 (인덱스 2)
if (enemies.Count > 2)
{
enemies.RemoveAt(2);
Debug.Log("Removed element at index 2");
}
// 리스트의 현재 요소 출력
Debug.Log("Current List:");
for (int i = 0; i < enemies.Count; i++)
{
Debug.Log(enemies[i].name);
}
}
}
//결과값
Added: Enemy0
Added: Enemy1
Added: Enemy2
Added: Enemy3
Added: Enemy4
Enemy Count: 5
Removed element at index 2
Current List:
Enemy0
Enemy1
Enemy3
Enemy
적 캐릭터 5마리를 들고 있는 List를 만들어 준 이후, Remove를 통해 2번째 인덱스 요소를 제거해 주었다.
Enemy2가 리스트에서 제거되고 그 상황에서 로그를 찍어보면 다음과 같이 결과가 나온다.
제거 후 리스트의 요소들이 자동으로 재정렬되어 빈 칸이 메꿔진다. Enemy3와 Enemy4가 한 칸씩 앞으로 이동하여 인덱스2와 인덱스3를 채운다. 다만 여기서 주의해야 할 것은 List<T>에서 요소를 추가하거나 제거할 때 리스트의 'Capacity'는 자동으로 조정되지 않는다는 사실이다. Capacity는 리스트가 요소를 저장하기 위해 할당한 메모리 크기를 나타내며, 'Count'는 실제로 리스트에 포함된 요소의 개수를 나타낸다.
- Capacity: 리스트가 현재 할당하고 있는 요소 저장 공간의 크기. 리스트의 요소가 증가할 때 자동으로 크기가 증가할 수 있지만, 감소할 때는 자동으로 줄어들지 않는다.
- Count: 리스트에 실제로 포함된 요소의 개수.
Capacity 예제
using System.Collections.Generic;
using UnityEngine;
public class ListExample : MonoBehaviour
{
// GameObject 타입의 리스트 선언
public List<GameObject> enemies;
void Start()
{
// 리스트 초기화
enemies = new List<GameObject>();
// Add: 요소 추가
for (int i = 0; i < 5; i++)
{
GameObject enemy = new GameObject("Enemy" + i);
enemies.Add(enemy);
Debug.Log("Added: " + enemy.name);
}
// Count와 Capacity 출력
Debug.Log("Enemy Count: " + enemies.Count);
Debug.Log("Enemy Capacity: " + enemies.Capacity);
// 가운데 요소 제거 (인덱스 2)
if (enemies.Count > 2)
{
enemies.RemoveAt(2);
Debug.Log("Removed element at index 2");
}
// Count와 Capacity 다시 출력
Debug.Log("Enemy Count after removal: " + enemies.Count);
Debug.Log("Enemy Capacity after removal: " + enemies.Capacity);
// 리스트의 현재 요소 출력
Debug.Log("Current List:");
for (int i = 0; i < enemies.Count; i++)
{
Debug.Log(enemies[i].name);
}
// Clear: 모든 요소 제거
enemies.Clear();
Debug.Log("Cleared all elements");
// Count와 Capacity 최종 출력
Debug.Log("Final Enemy Count: " + enemies.Count);
Debug.Log("Final Enemy Capacity: " + enemies.Capacity);
}
}
//결과값
Added: Enemy0
Added: Enemy1
Added: Enemy2
Added: Enemy3
Added: Enemy4
Enemy Count: 5
Enemy Capacity: 8 // 초기 Capacity 값은 다를 수 있다.
Removed element at index 2
Enemy Count after removal: 4
Enemy Capacity after removal: 8
Current List:
Enemy0
Enemy1
Enemy3
Enemy4
Cleared all elements
Final Enemy Count: 0
Final Enemy Capacity: 8
Capacity는 요소를 제거해도 자동으로 줄어들지 않는다. Capacity를 줄이려면 TrimExcess 메서드를 사용하여 현재 Count에 맞게 조정할 수 있다.
Capacity 조정 방법
enemies.TrimExcess();
Debug.Log("Trimmed Enemy Capacity: " + enemies.Capacity);
위 코드를 사용하여 Capacity를 조정할 수 있다. 요소를 제거한 후 TrimExcess를 호출하면 Capacity는 Count와 같아지거나 그보다 조금 더 클 수 있다.
'C# 자료구조, 알고리즘, 길찾기 > 선형자료' 카테고리의 다른 글
[자료구조] 스택(Stack)과 큐(Queue) 비교 (0) | 2024.06.10 |
---|---|
[C#] 배열 (Array) (0) | 2024.06.07 |