Класс ArrayList

Основным недостатком обычных массивов является то, что объем памяти, не­обходимый для хранения их элементов, должен быть выделен до начала работы с массивом. Класс ArrayList позволяет программисту не заботиться о выделении памяти и хранить в одном и том же массиве элементы различных типов.

По умолчанию при создании объекта типа ArrayList строится массив из 16 элементов
типа object. Можно задать желаемое количество элементов в массиве, передав его
в конструктор или установив в качестве значения свойства Capacity, например:


ArrayList arr1 = new ArrayList(): // создается массив из 16 элементов

ArrayList аrr2 = new ArrayList(1000); // создается массив из 1000 элементов

ArrayList аrrЗ = new ArrayList();

аrrЗ.Capacity = 1000; // количество элементов задается

Основные методы и свойства класса ArrayList перечислены в табл. 13.4.


Таблица 13.4. Основные элементы класса ArrayList


Элемент Вид Описание

Capacity Свойство Емкость массива (количество элементов, которые могут храниться в

массиве)
Count Свойство Фактическое количество элементов массива

Item Свойство Получить или установить значение элемента по заданному индексу

Add Метод Добавление элемента в конец массива

AddRange Метод Добавление серии элементов в конец массива

BinarySearch Метод Двоичный поиск в отсортированном массиве или его части

Clear Метод Удаление всех элементов из массива

Clone Метод Поверхностное копирование' элементов одного массива в другой массив

СоруТо Метод Копирование всех или части элементов массива в одномерный

массив

GetRange Метод Получение значений подмножества элементов массива в виде объекта типа

ArrayList

IndexOf Метод Поиск первого вхождения элемента в массив (возвращает индекс найденного

элемента или -1, если элемент не найден)

Insert Метод Вставка элемента в заданную позицию (по заданному индексу)

InsertRange Метод Вставка группы элементов, начиная с заданной позиции

LastIndexOf Метод Поиск последнего вхождения элемента в одномерный массив

Remove Метод Удаление первого вхождения заданного элемента в массив

RemoveAt Метод Удаление элемента из массива по заданному индексу

RemoveRange Метод Удаление группы элементов из массива

Reverse Метод Изменение порядка следования элементов на обратный

SetRange Метод Установка значений элементов массива в заданном диапазоне

Sort Метод Упорядочивание элементов массива или его части

TrimToSize Метод Установка емкости массива равной фактическому количеству элементов

Класс ArrayList реализован через класс Array, то есть содержит закрытое ноле этого класса. Поскольку все типы в С# являются потомками класса object, мас­сив может содержать элементы произвольного типа. Даже если в массиве хра­нятся обычные целые числа, то есть элементы значимого типа, внутренний класс является массивом ссылок на экземпляры типа object, которые представляют собой упакованный тип-значение. Соответственно, при занесении в массив вы­полняется упаковка, а при извлечении - распаковка элемента. Это не может не сказаться на быстродействии алгоритмов, использующих ArrayList.

Если при добавлении элемента в массив оказывается, что фактическое количест­во элементов массива превышает его емкость, она автоматически удваивается, то есть происходит повторное выделение памяти и переписывание туда всех суще­ствующих элементов.

Пример занесения элементов в экземпляр класса ArrayList:

arr1.Add(123);

arr1.Add(-2);

arr1.Add("Вася");

Доступ к элементу выполняется по индексу, однако при этом необходимо явным образом привести полученную ссылку к целевому типу, например:

int а = (int) arr1[0];

int b = (int) arr1[1];

string s = (string) arr1[2];

Попытка приведения к типу, несоответствующему хранимому в элементе, вызы­вает генерацию исключения InvalidCastException.

Для повышения надежности программ применяется следующий прием: экземп­ляр класса ArrayList объявляется закрытым полем класса, в котором необходимо хранить коллекцию значений определенного типа, а затем описываются методы работы с этой коллекцией, делегирующие свои функции методам ArrayList. Этот способ иллюстрируется в листинге 13.1, где создается класс для хранения объек­тов типа Monster и производных от него. По сравнению с аналогичным листингом из раздела «Виртуальные методы» (см. с. 178). в котором используется обычный массив, у нас появилась возможность хранить в классе Stado произвольное коли­чество элементов.

Листинг 13.1. Коллекция объектов

using System;

using System.Collections;

namespace ConsoleApplication1

{

class Monster

{

//...

}

class Daemon: Monster

{

//...

}

class Stado: IEnumerable

{

private ArrayList list;

public Stado() { list = new ArrayList(); }

public void Add(Monster m) { list.Add(m); }

public void RemoveAt(int i) { list.RemoveAt(i); }

public void Clear() { list.Clear(); }

public IEnumerator GetEnumeratcr() { return list.GetEnumerator(); }

}

class Class1

{

static void Main()

{

Stado stado = new Stado();

stado.Add(new Monster("Monia"));

stado.Add(new Monster("Monk"));

stado.Add(new Daemon("Dimon", 3));

stado.RemoveAt(1);

foreach (Monster x in stado)

x.Passport();

}

}

}

Результат работы программы:

Monster Monia health = 100 ammo - 100

Daemon Dimon health = 100 ammo - 100 brain = 3

Недостатком этого решения является то, что для каждого метода стандартной коллекции приходится описывать метод-оболочку, вызывающий стандартный метод. Хотя это и несложно, но несколько неизящно. В С#, начиная с версии 2.0, появились классы-прототипы (generics), позволяющие решить эту проблему. Мы рассмотрим их в следующем разделе.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: