본문으로 바로가기

[C#] 컬렉션, ArrayList

category 개발자과정준비/C# 2020. 8. 24. 00:17
반응형

컬렉션, ArrayList의 사용

컬렉션이란 같은 형의 데이터를 모아서 처리하는 자료구조이다. 배열도 컬렉션의 하나다. 컬렉션에는 "제네릭 컬렉션"과 "제네릭이 아닌 컬렉션"의 두 가지 유형이 있다. .NET Framework 2.0에서 추가된 제네릭 컬렉션은 컴파일 타임에 형식이 안전한(type-safe)컬렉션을 제공한다. 이로 인해 제네릭 컬렉션은 일반적으로 성능이 더 뛰어나다.

 

(1) 컬렉션의 공통 기능

 - 모든 컬렉션은 항목 추가, 제거 또는 찾기를 위한 방법을 제공한다.

 - 컬렉션을 열거하는 기능 : 모든 컬렉션을 Enumerable 도는 IEnumerable <T> 인터페이스를 구현하므로 열거할 수 있고, foreach문을 사용할 수 있다. IEnumerable<T>를 구현하는 모든 컬렉션은 LINQ를 사용하여 쿼리할 수 있다.

- 컬렉션의 내용을 배열에 복사하는 기능 : CopyTo 메서드를 사용하면 컬렉션을 배열에 복사할 수 있습니다. 결과 배열은 항상 1차원이며 하한은 0이다.

 

(2) 그 외의 기능

- Capacity 및 Count 속성 : 컬렉션의 Capacity는 컬렉션에 포함할 수 있는 요소의 수이고, 컬렉션의 Count는 컬렉션에 실제로 포함되어 있는 요소의 수이다. 대부분의 컬렉션은 현재 용량에 도달하면 자동으로 용량을 확장한다.

- 일관된 하한 : 컬렉션의 하한은 첫 번째 요소의 인덱스이다. System.Collections 네임스페이스의 모든 컬렉션은 하한이 0이다. 즉, 0부터 인덱싱 되는 것이다.

 

 아래의 표는 수행할 작업에 따라 어떤 컬렉션을 선택하는 것이 좋은지 표시해두었다. 제네릭과 제네릭이 아닌 컬렉션 중에서는 제네릭을 선택하는 것이 더 좋다고 한다.

 컬렉션의 예로 ArrayList를 사용해본다고해보자. ArrayList는 이름에서 알 수 있듯이 배열과 유사한 컬렉션이다. ArrayList의 가장 큰 장점은 배열과 달리 생성할 때 용량을 미리 지정할 필요없이 필요에 따라 자동으로 그 용량이 늘어나거나 줄어든다는 점이다. 

 

 ArrayList클래스의 메서드는 20여개가 되지만 예제에서는 이중 많이 사용되는 Add(), RemoveAt(), Insert(), Sort()를 사용해보자. Add()는 맨 뒤에 새 요소를 추가하고, RemoveAt()은 특정 인덱스에 있는 요소를 제거해준다. Insert()는 원하는 위치에 새 요소를 삽입하고 Sort()는 요소들을 정렬한다.

 

ArrayList에는 모든 타입의 값이 저장될 수 있다. ArrayList클래스의 메서드인 Add()를 보면 다음과 같이 정의되어있다.

public virtual int Add (object value);

즉, 매개 변수로 object 타입을 가지고 있는데 C#의 모든 형식은 object를 상속받기 때문에 어떠한 형식의 데이터도 저장이 가능하게 되는 것이다. 이것은 박싱(Boxing)과 언박싱(Unboxing)을 통해서 이루어진다. 그런데 박싱과 언박싱은 시간이 요구되는 작업이므로 ArrayList가 다루는 데이터가 많아지면 프로그램의 실행속도가 늦어지게 된다.

 

참고로 MSDN에서는 새로 프로그램을 작성할때 ArrayList보다 성능이 우수한 List<T>를 사용하라고 추천하고 있다. ArrayList를 사용하여 100까지의 랜덤 정수 10개를 저장하고 정렬한 후, 출력하는 프로그램을 작성해보자.

using System;
using System.Collections;
namespace _20200821_001Collection
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList a = new ArrayList();
            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); // ArrayList의 3번 인덱스를 제거한다.
            PrintValues(a);  // 프린트메서드를 호출해서 a에 저장된 값을 출력한다.
            // Count = 9가되고 3번 인덱스값이 제거된 것을 확인할 수 있다. capacity는 변화가 없다.
        }
        private static void PrintValues(ArrayList a)
        {
            Console.WriteLine("Print Values in ArrayList");
            Console.WriteLine("  Count = {0}", a.Count);
            Console.WriteLine("  Capacity = {0}", a.Capacity);
            foreach (var i in a)
                Console.Write("  {0}", i);
            Console.WriteLine();
        }
    }
}

실행화면

 

용량을 나타내는게 커페시티, 수는 카운트가 샌다.

배열 5개 만들면 5개 고정인데, 배열의 기능을 좀 더 개선한게 어레이리스트이다.

배열에서 값을 넣어주면 중간에 삽입이나 삭제하는 것이 불편한게 단점인데, 어레이리스트를사용하면 좀 더 쉽게 할 수 있다.

최상위 클래스인 오브젝트를 사용해서 인자를 아무거나 받을 수 있게 해놨다.

 

반응형