본문으로 바로가기
반응형

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