Коллекции в C#

Лекции по предмету «Программирование»
Информация о работе
  • Тема: Коллекции в C#
  • Количество скачиваний: 23
  • Тип: Лекции
  • Предмет: Программирование
  • Количество страниц: 7
  • Язык работы: Русский язык
  • Дата загрузки: 2015-01-04 00:04:15
  • Размер файла: 42.96 кб
Помогла работа? Поделись ссылкой
Информация о документе

Документ предоставляется как есть, мы не несем ответственности, за правильность представленной в нём информации. Используя информацию для подготовки своей работы необходимо помнить, что текст работы может быть устаревшим, работа может не пройти проверку на заимствования.

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

Коллекции в C#

Коллекция или контейнер это объект программы, который содержит экземпляры наборов данных и который позволяет управлять этой коллекцией. Под управлением коллекцией понимается выполнение добавления в коллекцию нового экземпляра, исключения экземпляра из коллекции, просмотр содержимого экземпляров, получение информации о количестве экземпляров в коллекции и т. д.
Перечисленные операции не зависят от типа данных, используемого в контейнере, но позволяют сократить затраты труда на написание программ для реализации этих операций. Для доступа к контейнеру достаточно добавить сборку System.Collections.Generic, содержащую методы для работы с коллекциями.
Контейнеры можно разделить на две группы:
• Последовательные контейнеры.
• Ассоциативные множества (словари).
Ниже указаны основные последовательные контейнеры:
• Список ArrayList необобщенный список. Объявляется без лексемы обобщения (<T>).
• Список List -обобщенный вариант класса ArrayList и
• Связный список (класс LinkedList).
Последовательные контейнеры различаются по способу вставки и исключения экземпляров наборов данных. Контейнер типа списка соответствует понятию одномерного массива в языке программирования, в котором элементы расположены в памяти компьютера строго последовательно, и обращение к элементам выполняется по индексу. Для вставки элемента в середину такого массива потребуется освободить место, занятое уже существующим элементом, а для этого надо переместить все элементы, которые должны следовать после вставляемого элемента на одну позицию по направлению к концу массива. При больших размерах массивов такая операция занимает значительное время. Аналогично для исключения элемента надо на его место переписать элемент, следующий за ним и т. д. С другой стороны, время доступа к элементу минимально, поскольку по индексу можно сразу вычислить адрес элемента в памяти.
В связных списках каждый элемент имеет указатель на следующий элемент, поэтому элементы в памяти могут размещаться в произвольном порядке, а, следовательно, для вставки элемента в середину списка требуется выделить для нового элемента память и настроить указатели так, чтобы новый элемент оказался в требуемом месте. Поэтому в связных списках время вставки (и исключения) элементов минимально (не зависит ни от размера списка, ни от места вставки), но для доступа к элементу данных требуется последовательный проход элементов, предшествующих искомому, что требует времени.
Независимо от типа и вида контейнера интерфейс для работы с контейнером стандартизован в том смысле, что одинаковые по назначению операции и параметры являются одинаковыми для всех контейнеров.
В коллекциях может применяться приведенная ниже конструкция:
«член класса» = default(T);
Такая конструкция обеспечивает инициализацию членов класса значениями по умолчанию.
Для всех коллекций вводится понятие перечисляемого типа данных, который поддерживается как в необобщенных интерфейсах IEnumerator и IEnumerable, так и в обобщенных интерфейсах IEnumerator<T> и IEnumerable<T>. Перечисляемый тип данных предоставляет возможность доступа к элементам коллекции. В каждой коллекции должен быть реализован обобщенный или необобщенный интерфейс IEnumerable, поэтому элементы любого класса коллекции должны быть доступны посредством методов, определенных в интерфейсе IEnumerator или IEnumerator<T>.
Необобщенный интерфейс позволяет орбрабатывать в цикле разнотипные элементы, для которых строится перечисляемый тип данных.
Это означает, что, внеся минимальные изменения в код циклического обращения к коллекции одного типа, его можно использовать для аналогичного обращения к коллекции другого типа.
Для поочередного обращения к содержимому коллекции в цикле foreach используется перечисляемый тип данных. С перечисляемым типом данных непосредственно связано другое средство, называемое итератором. Это средство упрощает процесс создания классов коллекций, например специальных, поочередное обращение к которым организуется в цикле foreach.
Ниже приведен пример программы для обработки обобщенного списка List. Элементом списка является класс List, содержащий 4 поля. В программе рассмотрено:
• Создание списка.
• Просмотр списка (вывод на экран).
• Сортировка списка (по умолчанию).
• Сортировка списка по заданному полю.
• Поиск элемента с заданным значением поля.
• Подсчет количества элементов с заданным значением поля.
• Фильтрация элементов списка.
Список создается из файла, в одной строке значения для одного элемента списка.
class Program
{
class Block: IComparable<Block> // Подключение интерфейса
{ // Описание класса
public string prof { get; set; }
public string name { get; set; }
public int skil;
public double wage;
public Block() { } // Пустой конструктор
public Block(string p, string s, int k, double w) // Конструктор с параметрами
{
prof = p;
name = s;
skil = k;
wage = w;
}
public int CompareTo(Block obj)
{
Block blk;
blk = (Block) obj;
int n = this.prof.CompareTo(blk.prof); // Сравнение по полю prof
return n;
}
public class sortOnSkill : IComparer<Block> // Для переключения поля
{ // Имя sortOnSkil произвольное, для каждого поля сравнения свое имя
public int Compare(Block a, Block b)
{
if (a.skil > b.skil) return 1; // Сравнение по полю skil
else if (a.skil < b.skil) return -1;
else return 0;
}
}
}
static void Main(string[] args)
{ // Файл поместить в папку Debug, либо прописывать полный путь
StreamReader file =
new StreamReader("C:\Temp\blocks.txt", Encoding.Default);
string s;
int sk;
double wg;
string[ ] str;
Block blk = new Block();
List<Block> lst = new List<Block>() ;
// Формирование списка из файла
while ((s = file.ReadLine()) != null)
{
str = s.Split(;); // Расщепление строки по точке с запятой(str - массив)
sk = int.Parse(str[2]); // Преобразование строки в число
wg = double.Parse(str[3]);
lst.Add(new Block(str[0],str[1], sk, wg)); // Добавить в блок
}
Console.WriteLine("Начальный список");
foreach (Block bl in lst) // Вывод начального списка
Console.WriteLine("{0,-12} {1,-8} {2} {3}", bl.prof, bl.name, bl.skil, bl.wage);
Console.WriteLine("
Сортировка по профессии");
lst.Sort(); // Сортировка по умолчанию
foreach (Block bl in lst) // Вывод сортированного списка
Console.WriteLine("{0,-12} {1,-8} {2} {3}",
bl.prof, bl.name, bl.skil,bl.wage);
Console.WriteLine("
Сортировка по квалификации");
// Вызов класса, изменяющего поле для сортировки
IComparer<Block> comp = new ArrayLst.Program.Block.sortOnSkill();
lst.Sort(comp);
foreach (Block bl in lst) // Вывод сортированного списка
Console.WriteLine("{0,-12} {1,-8} {2} {3}", bl.prof, bl.name, bl.skil, bl.wage);
Console.WriteLine("
Поиск");
blk = lst.Find(le => le.prof == "токарь" && le.name == "Иванов");
Console.WriteLine("{0,-12} {1,-8} {2} {3}",
blk.prof, blk.name, blk.skil, blk.wage);
Console.WriteLine("
Подсчет количества выбранных элементов");
int count = 0;
string fstr = blk.prof;// Блок blk был найден при поиске
foreach (Block bl in lst)
{
if (bl.prof == fstr) count++;// Количество блоков с заданным элементом
}
Console.WriteLine("Количество элементов "{0}" = {1}",fstr, count);
Console.WriteLine("
Выборка с помощью фильтра");
// Список flst для размещения отфильтрованных блоков
List<Block> flst = new List<Block>();
double fwg = lst[1].wage;// Выбрана зарплата
foreach (Block bl in lst)
{ // Фильтрация
if (bl.wage == fwg) flst.Add(new Block(bl.prof, bl.name, bl.skil, bl.wage));
}
foreach (Block bl in flst)
{ // Просмотр результатов фильтрации
Console.WriteLine("{0,-12} {1,-8} {2} {3}",
bl.prof, bl.name, bl.skil, bl.wage);
}
Console.ReadKey();
}
Не отлажена, ошибка здесь
//IComparer<Block> comp = new List<Block.sortOnSkill>();
IEnumerable<Block> comp = new List<Block.sortOnSkill>();
lst.Sort(comp);

Ниже представлен результат выполнения программы.

Классы Queue и Stack также являются последовательными контейнерами, но изменяют доступ к элементам контейнера для получения специализированных списков (очередей и стеков). Для обращения к элементам этих классов существуют специальные команды.
Для стека добавление элемента выполняется командой Push, просмотр командой Peek, и команда Pop извлекает элемент из списка.
static void Main(string[] args)
{
Stack<string> stc = new Stack<string>(); // Пустой стек
stc.Push("First"); // Добавление элемента в стек
stc.Push("Second");
stc.Push("Third");
stc.Push("Fourth");
Console.WriteLine("Вершина стека {0}
", stc.Peek());
string st = stc.Pop();// Извлечение в строку с извлечением из списка
Console.WriteLine("Извлечь с помощью Pop {0}"
+"

после команды Pop на вершине стека {1}", st,stc.Peek() );
Console.ReadKey();
}
Пример выполнения программы.

Для очереди добавление элемента выполняется командой Enqueue, а просмотр вершины очереди командой Peek, и команда Dequeue извлекает элемент из списка.
static void Main(string[] args)
{
Queue <string> qu = new Queue<string>();// Пустая очередь
qu.Enqueue("First"); // Добавление элемента в очередь
qu.Enqueue("Second");
qu.Enqueue("Third");
qu.Enqueue("Fourth");
Console.WriteLine("Вершина очереди {0}
", qu.Peek());
string st = qu.Dequeue();// Извлечение в строку с извлечением из списка
Console.WriteLine("Команда Dequeue извлекла: {0}"
+ "

после команды Dequeue на вершине очереди {1}", st,qu.Peek());
Console.ReadKey();
}
Пример выполнения программы.

При объявлении обобщенных контейнеров можно задать ограничения на классов или структур. Эти ограничения задаются с помощью ключевого слова where и позволяют учесть
В обобщенных контейнерах в качестве параметра указывается, по крайней мере, один тип данных. Платформа .NET позволяет помощью ключевого слова where наложить ограничение на тип данных, обрабатываемый в контейнере.
where T : struct Тип данных <T> должен быть структурой)
where T : class Тип данных <T> должен быть ссылочным типом
where T : new() Тип данных <T> должен иметь конструктор с параметрами. Это ограничение должно указываться последним.
where T : ИмяБазовогоКласса Тип данных <T> должен наследоваться от указанного класса.
where T : ИмяИнтерфейса Тип данных <T> должен реализовать, указанный интерфейс.
Из перечисленных ограничений наиболее важным является where T: new(), так как это требование на наличие конструктора с параметрами, и компилятор напомнит программисту о необходимости переопределения такого конструктора в объявлении класса. Ниже приведен пример
// Класс MyClass конструктор с параметрами
public class MyClass<T> where T : new()
{
}