Интерфейсы классов коллекций

advertisement
Высокоуровневые методы
информатики и
программирования
Лекция 15
Коллекции
Коллекции
Коллекции – классы, объекты которых
могут хранить ссылки на объекты
других классов (контейнеры)
Куча
Коллекция
Интерфейсы для работы с
коллекциями
Интерфейсы классов
коллекций
•
IEnumerable - Составляет список объектов классов коллекций с помощью оператора
foreach
•
IComparer - Сравнивает два объекта классов коллекций при их сортировке;
•
ICollection - Реализуется всеми классами коллекций для обеспечения доступа к методу
СоруТо(), GetEnumerator() и свойство Count;
•
IList - Используется объектами классов коллекций, индексируемыми как массив.
•
IDictionary - Используется классами коллекций, осуществляющими доступ по ключу или
значению, таких как Hashtable и SortedList.
•
IDictionaryEnumerator - Позволяет просмотреть (с помощью оператора foreach) объекты
классов коллекций, поддерживающих интерфейс IDictionary
Интерфейс IEnumerable
interface IEnumerable
{
IEnumerator GetEnumerator();
}
interface IEnumerator
{
public bool MoveNext(); // i++
public void Reset();
// i=0;
public оbject Current {get;}); //property
}
Коллекции
• System.Array - массивы – простейший тип
коллекций
– фиксированный размер
– однотипные объекты
• System.Collections.
– ArrayList – неограниченный список
элементов.
– Queue – порядок элементов FIFO
– Stack – порядок элементов LIFO
– Hashtable – словарь (ключ - значение),
оптимизирован для быстрого поиска значний.
Коллекции в .NET
• System.Collections
– Нетипизированные коллекции
– Специализированные коллекции
• System.Collections.Generic
– Шаблонные коллекции
Основные элементы
интерфейса ICollection
Элемент
Описание
Count
свойство – количество объектов в коллекции
CopyTo()
метод копирования элементов коллекции в массив
типа Array, начинас с заданного индекса массива
GetEnumerator() получение объекта, поддерживающего интерфейс
IEnumerable), который позволяет просматривать
всю коллекцию (для foreach)
Основные элементы
интерфейса IList
Элемент
Add()
метод добавления объекта к коллекции
Clear()
удаление всех объектов из коллекции
Contains()
проверка на наличие в коллекции объекта (true/false)
IndexOf()
определение индекса для заданного объекта
Insert()
вставка объекта в место заданное индексом
Remove()
удаление первого встреченного экземпляра указанного
объекта
удаление всех объектов, начиная с заданного индекса
RemoveAt()
[index]
Описание
индексатор, который позволяет получить или задать объекты
по заданному индексу.
Основные элементы интерфейса
IDictionary
• Описывает не обобщенную коллекцию пар (ключ,
значение)
• Основные методы:
– Add() – добавляет элемент с заданным ключем и значением;
– Clear() – удаляет все элементы из словаря;
– Contains () – проверяетсодержит ли словарь заданный
элемент;
– CopyTo() – копирует элементы ICollection в массив начиная с
заданного индекса массива (наследуется от ICollection);
– GetEnumerator() – перегруженный метод для получения
объекта Enumerator.
– Remove () – удаление всех элементов с заданным ключем из
объекта IDictionary.
Типы нетипизированных коллекций
• ArrayList – простая коллекция (наследуется от интерфейса IList),
которая может хранить объекты любого типа. Экземпляры
ArrayList могут хранить произвольное количество объектов, при
необходимости, они увеличивают объем используемой памяти.
• Queue – коллекция, которая поддерживает следующий порядок
работы с объектами: «первым пришел, первым вышел» (first-in,
first-out – FIFO). Можно использовать Queue на сервере
обработки сообщений, для временного хранения сообщений
перед обработкой, или для хранения информации о клиентах,
которые должны обрабатываться в порядке «Первым – пришел,
первым – ушел».
• Stack – коллекция, которая поддерживает следующий порядок
работы с объектами: «Последним пришел – первым ушел» (lastin, first-out – LIFO). Можно использовать Stack для хранения
наиболее новых изменений, чтобы можно было их отменить.
Класс ArrayList
• Реализует интерфейсы IList, ICollection, IEnumerable,
ICloneable, используя массив, размер которого
динамически меняется по необходимости.
ArrayList arl = new ArrayList( );
• Свойства
– Сount – количество элементов
– Capacity – текущий объем списка
– Item – получение элемента по индексу (indexer [ i ] –
операция)
• Методы
–
–
–
–
Add( ) – добавить объект
Clear( ) – очистить
Sort( ) – сортировать
…
Пример работы
ArrayList al = new ArrayList();
al.Add("Привет");
al.Add("Мир");
al.Add(5);
al.Add(new FileStream("delemete", FileMode.Create));
Console.WriteLine("Коллекция содержит " + al.Count +
" элемента:");
foreach (object s in al)
Console.Write(s.ToString() + " ");
• Результат
Коллекция содержит 4 элемента:
Привет Мир 5 System.IO.FileStream
ArrayList al = new ArrayList();
ArrayList al = new ArrayList() {"Привет",
"Мир", "это", "проверка"};
al.Remove("это");
al.Insert(1, "Наш");
al.Sort();
foreach (object s in al)
Console.Write(s.ToString() + " ");
• Результатом работы будет следующая
строка:
Мир Наш Привет проверка
Метод преобразования коллекции к типу
OfType<T>()
•
В не типизированных коллекциях могут храниться данные любого
типа.
• Для применения LINQ нужно выбрать из них только те, которые
имеют определенный тип (преобразовать в типизированную
коллекцию)
• Метод OfType<T>() выбирает из нетипизированной коллекции
только объекты заданного типа и преобразует их к типу
IEnumerable<TResult>.
• Например:
// Extract the ints from the ArrayList.
ArrayList myStuff = new ArrayList();
myStuff.AddRange(new object[]
{ 10, 400, 8, false, new Car(), "string data" });
IEnumerable<int> myInts = myStuff.OfType<int>();
// Prints out 10, 400, and 8.
foreach (int i in myInts)
{
Console.WriteLine("Int value: {0}", i);
}
Класс очередей (Queue)
• Очередь (queue) - это класс коллекций,
организованный по принципу FIFO
(первым вошел - первым вышел).
Классическая аналогия - очередь в
кассу за билетами. Первый человек,
стоящий в очереди, первый и выйдет из
нее, когда купит билет.
• Очередь удачно подходит для
управления ограниченными ресурсами.
Свойства и методы очереди
• Свойство
– Count - Открытое свойство, позволяющее узнать
текущее количество элементов очереди
• Методы
– Enqueue() - Добавляет объект в конец объекта Queue
– Dequeue() - Возвращает объект, стоящий в начале
объекта Queue, и удаляет его из очереди
– Peek() - Возвращает объект, стоящий в начале
объекта Queue, не удаляя его
– Contains () - Выясняет, находится ли данный элемент
в объекте Queue
– Clear() - Удаляет все элементы из объекта Queue
Queue q = new Queue();
q.Enqueue("Привет");
q.Enqueue("мир");
q.Enqueue("просто тестирование");
Console.WriteLine("Использование Queue:");
for (int i = 1; i <= 3; i++)
Console.WriteLine
(q.Dequeue().ToString());
• Результат:
Использование Queue:
Привет
мир
просто тестирование
Класс Stack (Стек)
• это класс коллекции, организованный по принципу LIFO
(последним вошел- первым вышел).
• Аналогией может служить стопка подносов в столовой
самообслуживания (или, например, столбик из монет).
Поднос, положенный в стопку последним, будет взят
оттуда первым.
• Основными методами для работы со стеком являются
Push ( ) (добавление элемента) и Рор() (удаление).
• Кроме того, класс Stack предоставляет метод Peek(),
аналогичный одноименному методу класса Queue.
Свойства и методы стека
• Свойство
– int Count – количество элементов стека
• Методы
– void Push() – Помещает объект на вершину
объекта Stack
– object Pop() - Возвращает объект, находящийся на
вершине объекта Stack, и удаляет его из стека
– object Peek() – Возвращает объект, находящийся
на вершине объекта Stack, не удаляя его
– void Clear() – убрать все объекты
– bool Contains(a) – проверка есть элемент
Пример работы со стеком
Stack s = new Stack();
s.Push("Привет");
s.Push("мир");
s.Push("просто тестирование");
Console.WriteLine("\nИспользование Stack:");
for (int i = 0; i < 3; i++)
Console.WriteLine
(s.Pop().ToString());
• Результат:
Stack demonstration:
просто тестирование
мир
Привет
Словари
• Классы словарей (dictionaries) задают соответствие между
ключами (key) и значениями (value). Например, можно связать
идентификатор сотрудника (например, табельный номер) с
объектом класса, описывающего сотрудника номер.
• Значение словаря можно найти по значению ключа:
– значение = словарь [ключ];
Ключ
Словарь
Ссылка
Куча
Типы нетипизированных словарей
• Классы словарей (dictionaries) задают соответствие
между ключами (key) и значениями (value). Например,
можно связать идентификатор сотрудника (например,
табельный номер) с объектом класса, описывающего
сотрудника номер. В FCL включены следующие основные
классы словарей:
• Hashtable – словарь (хешированная таблица) пар (имя,
значение), которые могут быть получены по имени или
индексу;
• SortedList – словарь, который автоматически сортируется
по ключу;
• StringDictionary – словарь Hashtable в котором пары
имя/значение могут быть только строками string.
Отсортированный список
SortedList
• Поддерживает интерфейсы
IDictionary, ICollection, IEnumerable,
ICloneable
• Представляет собой коллекцию пар
(ключ, значение), которые сортируются
по ключу и доступны
– по ключу [ключ] и
– индексу [i].
SortedList sl = new SortedList();
sl.Add("Stack", "Коллекция объектов типа LIFO.");
sl.Add("Queue", "Коллекция объектов типа FIFO.");
sl.Add("SortedList", "Коллекция пар ключ/значение.");
foreach (DictionaryEntry de in sl)
Console.WriteLine(de.Value);
string s = (string)sl["Queue"];
// s = "Коллекция объектов типа FIFO.«
Класс Hashtable (Хеш-таблица)
• это словарь, оптимизированный для
максимально быстрого получения
информации.
• Хранение пар (ключ, значение) организовано в
соответствии с хэш кодом ключа.
• В объекте Hashtable каждое значение хранится
в блоках. Блоки пронумерованы, чем
напоминают элементы массива.
• Поскольку ключ может и не быть целым
числом, нужен способ преобразования ключа
(например строки “Иванов”) в номер блока.
• Каждый ключ обязан предоставить метод
GetHashCode(), выполняющий это действие.
Хеш-код (продолжение)
• Стандартная реализация метода GetHashCode() для строки
сводится к тому, что Unicode-коды всех символов строки
складываются, а затем с помощью деления по модулю
получается значение от 0 до N, где N - количество блоков в
хеш-таблице. Писать такой метод для типа string не надо,
так как среда CLR предоставляет его по умолчанию.
• Когда в объект Hashtable вставляются значения, он вызывает
метод GetHashCode() для каждого указанного ключа. Метод
возвращает целочисленное значение, идентифицирующее
блок, в который помещено значение.
• Не исключена ситуация, когда для нескольких ключей будет
возвращен один номер блока. Это называется конфликтом
(collision). Существует ряд способов разрешения конфликтов.
Самым распространенным подходом, к тому же принятым в
CLR, является ведение упорядоченного списка значений в
каждом блоке.
Свойства и методы Hashtable
• Свойства
– Count – текущее число элементов
– [ ] – индексатор
• Методы
– Clear() - Удаляет все элементы из объекта
Hashtable
– Add(object k, object v) - Добавляет запись с
указанной парой ключ/значение
– Remove() - Удаляет запись с указанным ключом
– ContainsKey () - проверить наличие заданного
ключа.
– ContainsValue () - проверить наличие заданного
значения.
Универсальные классы
(Generic classes)
Обобщения (generics)
• Под обобщением (универсальностью, generality) понимается
способность типа объявлять используемые им другие типы как
параметры.
• Класс с параметрами, задающими типы, называется
обобщенным или универсальным классом (generic class).
• Обобщенными могут быть:
–
–
–
–
классы
методы
делегаты
интерфейсы
Обобщенные классы
(Generic Classes)
class MyClass<T1, ... Tn> {...}
• Пример обобщенного класса:
public class Point<T>
{
//координаты точки, тип которых задан параметром
T x, y;
// другие свойства и методы структуры
...
}
• При описании переменной данного типа нужно задать конкретный
используемый тип.
• Например:
Point<int> pt;
pt = new Point<int> ();
Пример обобщенного метода:
class Change
{
static public void Swap<T>(ref T x1, ref T x2)
{
T temp;
temp = x1; x1 = x2; x2 = temp;
}
}
Использование обобщенного
метода
public void TestSwap()
{
int x1 = 5, x2 = 7;
Change.Swap<int>(ref x1, ref x2);
erson pers1 = new Person("Савлов", 25, 1500);
Person pers2 = new Person("Павлов", 35, 2100);
Change.Swap<Person>(ref pers1, ref pers2);
}
Стандартные обобщенные делегаты
•
•
•
•
•
•
•
В библиотеке FCL описаны стандартные обобщенные делегаты,
которые активно используются в методах классов библиотеки:
System.Action() – принимает значение (или значения) и ничего не
возвращает;
public delegate void Action<T>( T obj )
System.Comparison() – принимает два параметра и возвращает целое
значение (< 0: x < y; 0: x == y; > 0: x > y)
public delegate int Comparison<T>( T x, T y )
System.Converter() – преобразование объекта из одного типа в другой
public delegate TOutput Converter<TInput, Toutput> ( TInput input )
System.EventHandler – обработчик событий
public delegate void EventHandler<TEventArgs>
( Object sender, TEventArgs e ) where TEventArgs : EventArgs
System.Func() – принимает значение (или значения) и возвращает
результат
public delegate TResult Func<T, TResult>( T arg )
System.Predicate() – принимает значение и возвращает bool
public delegate bool Predicate<T>( T obj )
Стандартные обобщенные
интерфейсы
•
•
•
•
•
•
ICollection<T>
IComparer<T>
IDictionary<TKey, TValue>
IEnumerable<T>
IEnumerator<T>
IList<T>
Стандартные пространства
имен
•
•
•
•
•
System – содержит основные базовые классы;
System.Collections – содержит интерфейсы и классы, которые
описывают разные типы коллекций и словарей (не обобщенные).
System.Collections.Generic содержит интерфейсы и классы, которые
описывают обобщенные коллекции и словари, которые позволяют
пользователям создавать строго типизированные коллекции,
предоставляющие лучшую безопасность работы с типами и лучшую
производительность, чем не обобщенные коллекции;
System.Linq содержит классы и интерфейсы, которые поддерживают
интегрированный в язык C# язык запросов - Language-Integrated Query
(LINQ).
System.Text содержит классы представляющие методы кодировки
символов ASCII, Unicode, UTF-7 и UTF-8; абстрактные базовые классы
для конвертирования наборов символов в набор байтов; и
вспомогательный класс для манипулирования и форматирования
String объектов без создания промежуточных экземпляров типа String.
Обобщенные коллекции из
System.Collections.Generic
• List<тип> - список элементов
переменного размера;
• Queue <тип> – порядок элементов
FIFO;
• Stack <тип> – порядок элементов LIFO;
• LinkedList<тип> - двухсвязный список;
• Dictionary<TKey, TValue> (dictionary –
коллекция, которая ассоциирует ключ
(key) со значением (value))
Соответствие между обобщенными
классами и их обычными двойниками
Универсальный класс
Обычный класс
List<T>
ArrayList
Queue<T>
Queue
Stack<T>
Stack
SortedDictionary<K,T>
SortedList
Dictionary<K,T>
LinkedList<T>
HashTable
нет
Пример использования
Stack<Point> sp;
sp = new Stack<Point>();
sp.Push(p);
Point[ ] pa;
pa = sp.ToArray();
public class Person : IComparable
{
string firstName, lastName;
public int CompareTo(object obj)
{
Person otherPerson = (Person)obj;
if (this.lastName != otherPerson.lastName)
return this.lastName.CompareTo(otherPerson.lastName);
else
return this.firstName.CompareTo (otherPerson.firstName);
}
public Person(string _firstName, string _lastName){
firstName = _firstName; lastName = _lastName;
}
override public string ToString() {
return firstName + " " + lastName;
}
}
List<Person> group = new List<Person>();
group.Add(new Person("Григорий", "Дубина"));
group.Add(new Person("Иван", "Ходырев"));
group.Add(new Person("Александр", "Луценко"));
group.Sort();
foreach (Person p in group)
Console.Write(p.ToString() + ";");
SortedList<string, int> sl = new
SortedList<string, int>();
sl.Add("One", 1);
sl.Add("Two", 2);
sl.Add("Three", 3);
foreach (int i in sl.Values)
Console.Write(i.ToString() + " ");
int n = sl[“Two”]; // значение 2
• Результат выполнения примера:
132
Словарь
Dictionary <TKey, Tvalue>
• Словарь (dictionary) - это класс
коллекции, связывающий ключ со
значением.
• По такому же принципу построены
толковые словари, например словарь
Вебстера связывает слово (ключ) с его
толкованием (значение).
Свойства и методы IDictionary
• Свойство
– Item – получить или записать элемент
– Keys – получить ICollection всех ключей
– Values - получить ICollection всех значений
• Методы
– Add() – добавить ключ и значение к словарю;
– Clear() – удалить все ключи и значения из
словаря;
– Remove () – удалить значение с указанным
ключем;
– bool ContainsKey(key) – определить есть ли в
словаре указанный ключ;
– bool ContainsValue(value) - определить есть ли в
словаре указанное значение;
– bool TryGetValue(key, out value) - получить
значение связанное с заданным ключом.
Download