List<T> 컬렉션
List<T> 컬렉션 클래스는 C# 프로그래밍에서 동적으로 생성되고 삭제되는 자료를 저장할 때 가장 빈번하게 사용된다고한다. 배열과 달리 크기가 가변이고, 제네릭 컬렉션이기 때문에 T에 어떠한 자료형도 넣을 수 있는 리스트이다. 예를들어 int의 리스트는 다음과 같이 생성된다.
List<int> list = new List<int>();
List<T>는 제네릭 컬렉션이므로 System.Collections.Generic을 using문으로 포함시켜서 사용한다. 일반적으로 제네릭 컬렉션이 성능이 좋기 때문에 ArrayList를 쓸 경우가 있을때에는 대신 List<T>를 사용하는 것이 권장된다. 참고로 제네릭 컬렉션에는 LinkedList<T>도 있다. 이름뿐 아니라 사용법도 비슷해서 List<T>와 혼동되는데, LinkedList<T>는 이중 연결 리스트이다. 예제를 살펴보자.
using System;
using System.Collections.Generic;
namespace _20200821_001
{
class Program
{
static void Main(string[] args)
{
List<int> a = new List<int>();
Random r = new Random();
PrintValues(a); // 정렬하기 전에 프린트를 호출해서 a에 저장된 값을 출력한다. 값을 넣지 않았으므로 Count와 capacity 속성의 값은 0이다.
for (int i = 0; i < 10; i++) // 10번 반복해서 a에 0~100까지의 랜덤 숫자를 저장한다.
a.Add(r.Next(100));
PrintValues(a); // 정렬하기전에 프린트메서드를 호출해서 a에 저장된값을 출력해본다. Count 속성은 10, capacity속성은 16으로 출력된다.
a.Sort(); // a의 값을 정렬하고 프린트메서드로 a에 저장된 값을 출력한다.
PrintValues(a);
a.RemoveAt(3); // List<T>의 3번 인덱스의 값을 제거한다.
PrintValues(a); // 프린트메서드를 호출해서 a에 저장된 값을 출력한다.
// Count = 9가되고 3번 인덱스값이 제거된 것을 확인할 수 있다. capacity는 변화가 없다.
}
private static void PrintValues(List<int> a)
{
Console.WriteLine("Print Values in List<int>");
Console.WriteLine(" Count = {0}", a.Count);
Console.WriteLine(" Capacity = {0}", a.Capacity);
foreach (var i in a)
Console.Write(" {0}", i);
Console.WriteLine();
}
}
}
위의 예제는 랜덤 숫자를 저장할 객체를 생성하고, a에 for문으로 0~99까지 랜덤 숫자를 저장한다.
첫번째 출력은 아무것도 저장 안한상태에서 출력
두번째 출력은 생성된 배열을 출력
세번째 출력은 오름차순 정렬을 시킨 배열을 출력
네번재 출력은 List<3>을 RemoveAt을 시킨 배열을 출력한다.(RemoveAt은 List<T>에서 지정한 인덱스를 제거한다)
네번째 출력에서 List<3>의 자리인 "33"이 제거된 것을 확인할 수 있고, Count가 9로 1줄어든 것을 확인할 수 있다.
근데 capacity는 왜 16이 출력되는 걸까?
해당 코드를 치고 실행해보자.
static void Main(string[] args)
{
List<int> aList = new List<int>();
Console.WriteLine("Capacity : {0}, Count : {1}", aList.Capacity, aList.Count);
aList.Add(100);
Console.WriteLine("Capacity : {0}, Count : {1}", aList.Capacity, aList.Count);
aList.Add(100);
Console.WriteLine("Capacity : {0}, Count : {1}", aList.Capacity, aList.Count);
aList.Add(100);
Console.WriteLine("Capacity : {0}, Count : {1}", aList.Capacity, aList.Count);
aList.Add(100);
Console.WriteLine("Capacity : {0}, Count : {1}", aList.Capacity, aList.Count);
aList.Add(100);
Console.WriteLine("Capacity : {0}, Count : {1}", aList.Capacity, aList.Count);
}
aList 에 100을 1개 추가할때 Capacity의 공간은 4개가 미리 할당한 것을 확인할 수 있다. 4개까지는 추가하지않다가 5개가 되었을때는 8개로 미리 할당해둔 것을 볼 수 있다.
이로 인해 컬렉션의 Capacity는 현재 용량에 도달하면 자동으로 용량을 확장해줄 수 있는 것을 확인할 수 있다.
List<T>와 배열의 정렬
리스트와 배열은 만드는 방법과 사용하는 방법이 서로 다르다. 우선 List<T>와 Array는 객체 생성 방법이 다르다.
List<string> lstNames = new List<string>();
Array<string> arrNames = new Array<string>(); // 에러
Array arrNames = new Array(); // 에러
List<T>는 위와 같이 new 키워드와 클래스 이름을 사용하여 만들지만 배열은 다음과 같이 만들어야한다.
string[] arrName = new string[100];
정렬하는 메서드 Sort()는 List<T> 클래스에도 있고 Array 클래스에도있다. 하지만 이 둘 역시 사용법이 다르다.
lstNames.Sort();
arrNames.Sort(); // 에러
배열 이름 뒤에는 Sort() 메서드를 사용할 수 없다. Array 클래스의 Sort 메서드는 static으로 정의되어있기 때문에 클래스의 이름과 함께 Array.Sort(배열 이름)형태로 사용한다.
Array.Sort(arrName);
리스트와 배열은 자료를 저장하는 가장 기본적인 자료구조이다. 하지만 둘의 사용법이 다르다는 것을 기억해야 한다.
using System;
using System.Collections.Generic;
namespace _20200821_001Array_Sort
{
class Program
{
static void Main(string[] args)
{
List<string> lstNames = new List<string>(); // List<string> 클래스의 인스턴스 lstNames를 생성
lstNames.Add("dog"); // Add 메서드로 5개의 값을 리스트에 저장
lstNames.Add("cow");
lstNames.Add("rabbit");
lstNames.Add("goat");
lstNames.Add("sheep");
lstNames.Sort(); // Sort() 메서드로 정렬
foreach (string s in lstNames) // 정렬된 리스트의 내용을 출력
Console.Write(s + " ");
Console.WriteLine();
string[] arrNames = new string[100]; // 인덱스를 사용하여 5개의 값을 배열에 저장
arrNames[0] = "dog";
arrNames[1] = "cow";
arrNames[2] = "rabbit";
arrNames[3] = "goat";
arrNames[4] = "sheep";
Array.Sort(arrNames); // Array.Sort(arrNames) 메서드를 사용하여 배열을 정렬
foreach (var s in lstNames) // 정렬된 배열의 내용을 출력
Console.Write(s + " ");
Console.WriteLine();
}
}
}
'개발자과정준비 > C#' 카테고리의 다른 글
[C#] LiNQ (0) | 2020.08.29 |
---|---|
[C#] IComparable 인터페이스를 이용한 객체의 정렬 (0) | 2020.08.28 |
[C#] 컬렉션, ArrayList (0) | 2020.08.24 |
[C#] Random 클래스 (0) | 2020.08.23 |
[C#] 제네릭 프로그래밍(메서드, 클래스) (2) | 2020.08.19 |