Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Универсальные коллекции языка С#. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
Демонстрируется использование метода TryGetValue как более эф­фективный способ получения значений, если в программе часто ис­пользуются значения ключей, которые не находятся в сортированном списке, а также показано, как использовать метод ContainsKey для проверки наличия ключа перед вызовом метода Add.
Показано, как перечислить ключи и значения в сортированном списке, а также как перечислить только
ключи и значения с помощью свойства Keys и свойства Values. Демонстрируется использование ме­тода Remove для удаления элемента по ключу.
usingSystem; usingSystem.Collections.Generic;
namespaceПример_1 {
classProgram { //Методдлявыводасловарянаэкран. staticvoidPrint<TKey,TValue>(inSortedList<TKey,TValue>cnt,stringheader) { Console.WriteLine(header); foreach(varpareincnt) { Console.WriteLine($"{pare.Key,15}{pare.Value,10}"); } Console.WriteLine(); }  staticvoidMain(string[]args) { //Городамилионники.Населениевтысячахчеловек. //Создаетновыйсортированныйсписокцелыхчисел, SortedList<string,int>cyties=newSortedList<string,int>() { {"Челябинск",1196}, {"Омск",1154}, {"Самара",1156}, {"Ростов‐на‐Дону",1137}, {"Уфа",1128}, };
состроковымиключами.
51
Print(cyties,"Городамилионники:"); //Добавляемнесколькоэлементовксловарю.Внихнедолжнобыть //дубликатовключейсловаря, //нонекоторыезначениямогутдублироваться. cyties.Add("Красноярск",1093); cyties.Add("Пермь",1055); //МетодAddmethodвыбрасываетисключение, //еслиновыйключужеестьвсловаре. Print(cyties,"Городамилионникипоследобавления:"); try { cyties.Add("Самара",1156); } catch(ArgumentException) { Console.WriteLine("Элементсключом=\"Самара\"Ужесуществует."); } //СвойствоItemявляетсядругимименемдляиндексатора //можноопускатьегоимяприобращениикэлементам. Console.WriteLine("Дляключа=\"Омск\",value={0}.", cyties["Омск"]); //Индексможноиспользовать,чтобыизменитьзначениесвязанного //снимключа. cyties["Пермь"]=1057; Console.WriteLine("Дляключа=\"Пермь\",value={0}.", cyties["Пермь"]); //Еслиключнесуществует,присваиваниеиндексаторудляэтогоключа //добавляетновуюпаруключ/значение(key/value). cyties["Воронеж"]=1058; //Индексаторвыбрасываетисключение,еслизапрашиваемогоключанет //всловаре. try
{
 Console.WriteLine("Forkey=\"tif\",value={0}.", cyties["Краснодар"]); } catch(KeyNotFoundException) { Console.WriteLine("Ключ=\"Краснодар\"несуществует."); } //Когдапрограммачастодолжназапрашиватьключи,которыхможет //неоказатьсявсловаре, //TryGetValueможетстатьболееэффективнымпутемизвлекатьзначения.
,такчто
52
intvalue; if(cyties.TryGetValue("",outvalue)) { Console.WriteLine("Дляключа=\"Челябинск\",value={0}.",value); } else { Console.WriteLine("Ключ=\"Челябинск\"Ненайден."); } //ContainsKeyможноиспользоватьдляпроверкиключейпередихвставкой. if(!cyties.ContainsKey("ht")) { cyties.Add("Волгоград",1008); Console.WriteLine("Значениедобавленодляключа=\"Волгоград\":{0}", cyties["Волгоград"]); } //Когдавыиспользуете //элементыизвлекаютсякакKeyValuePairобъекты. Console.WriteLine(); foreach(KeyValuePair<string,int>kvpincyties) { Console.WriteLine("Ключ={0,15},Значение={1,10}", kvp.Key,kvp.Value); } //Чтобыполучитьтолькозначения,используйтесвойствоValues. Console.WriteLine(); foreach(intvalincyties.Values) { Console.WriteLine("Значение={0}",val); } //Чтобыполучитьтолькоключи,используйтесвойствоKeys. Console.WriteLine(); foreach(stringkey { Console.WriteLine("Ключ={0}",key); }  //ТспользуйтеметодRemoveчтобыудалитьпаруключ/значение(key/value). Console.WriteLine("\nRemove(\"Челябинск\")"); cyties.Remove("Челябинск"); if(!cyties.ContainsKey("Челябинск")) { Console.WriteLine("Ключ\"Челябинск\"ненайден."); }
foreachперебораэлементовсловаря,
incyties.Keys)
53
} } }  Результатработыпримера: Городамилионники: Омск1154 Ростов‐на‐Дону1137 Самара1156 Уфа1128 Челябинск1196  Городамилионникипоследобавления: Красноярск1093 Омск1154 Пермь1055 Ростов‐на‐Дону1137 Самара1156 Уфа1128 Челябинск1196  Элементсключом="Самара"Ужесуществует. Дляключа="Омск",value=1154. Дляключа="Пермь",value=1057. Ключ="Краснодар"несуществует. Ключ=
"Челябинск"Ненайден.
Значениедобавленодляключа="Волгоград":1008  Ключ=Волгоград,Значение=1008 Ключ=Воронеж,Значение=1058 Ключ=Красноярск,Значение=1093 Ключ=Омск,Значение=1154 Ключ=Пермь,Значение=1057 Ключ=Ростов‐на‐Дону,Значение=1137 Ключ=Самара,Значение=1156 Ключ=Уфа,Значение=1128 Ключ=Челябинск,Значение=1196  Значение=1008 Значение=1058 Значение=1093 Значение=1154 Значение=1057 Значение=1137 Значение=1156
54
Значение=1128 Значение=1196  Ключ=Волгоград Ключ=Воронеж Ключ=Красноярск Ключ=Омск Ключ=Пермь Ключ=Ростов‐на‐Дону Ключ=Самара Ключ=Уфа Ключ=Челябинск  Remove("Челябинск") Ключ"Челябинск"ненайден.
КОЛЛЕКЦИЯ LINKEDLIST<T> – ДВУСВЯЗНЫЙ СПИСОК
Объект класса LinkedList<T> представляет собой двусвязный спи­сок, в котором каждый элемент ссылается на следующий и предыду­щий, как показано на рисунке.
Следующий Значение Предыдущий
Следующий Значение Предыдущий
Следующий Значение Предыдущий
Преимущество двусвязного списка проявляется в том, что опера­ция вставки элемента в середину выполняется очень быстро. При этом только ссылки Next (следующий) предыдущего элемента и Previous (предыдущий) следующего элемента должны быть изменены так, что­бы указывать на вставляемый элемент. Этим он отличается от коллек­ции List<T>, в которой при вставке нового элемента
все последующие
должны быть сдвинуты.
Недостаток двусвязного списка в том, что элементы двусвязных списков доступны лишь друг за другом. Поэтому для нахождения эле­мента, находящегося в середине или конце списка, требуется довольно
55
много времени. В двусвязном списке информация пользователя хра­нится в узлах списка – объектах класса LinkedList<T> вместе со слу­жебной информацией о следующем и предыдущем узле списка. По­этому LinkedList<T> является двусвязным списком узлов типа
LinkedListNode<T>.
С помощью объектов класса LinkedListNode<T> появляется воз­можность обратиться к предыдущему и последующему элементу спис­ка. Класс LinkedListNode<T> определяет свойства List, Next, Previous и Value. Свойство List возвращает объект LinkedList<T>, с которым узел ассоциирован. Свойства Next и Previous предназначены для ите­раций по списку, для доступа к следующему и предыдущему элементу. Свойство Value типа T возвращает элемент, ассоциированный с узлом.
Класс LinkedList<T> определяет свойства для доступа к первому (First) и последнему (Last) узлу в списке, методы для вставки элемен­тов в определенные позиции: AddAfter() –
вставляет после заданного узла, AddBefore() – вставляет перед заданным узлом, AddFirst() – вставляет узел в начало, AddLast() – вставляет узел в конец; для удале­ния элементов из заданных позиций: Remove() – удаляет первое вхож­дение заданного значения, RemoveFirst() – удаляет первый узел, RemoveLast() – удаляет последний узел; для нахождения элементов, начиная поиск либо с начала списка Find() – находит первое вхожде­ние заданного значения,
либо с конца списка FindLast() – находит по-
следнее вхождение заданного значения.
В классе LinkedList<T> реализуются интерфейсы ICollection, ICol-
lection<T>, IEnumerable, IEnumerable<T>, ISerializable и IDeserializa­tionCallback (см. раздел Интерфейсы). В двух последних интерфейсах
поддерживается сериализация списка. В классе LinkedList<T> опреде­ляются два приведенных ниже открытых конструктора и свойства.
Конструкторы Назначение
LinkedList<T>() Инициализирует новый экземпляр пустого
класса LinkedList<T>
LinkedList<T>(IEnumerable<T>) Инициализирует новый экземпляр класса
LinkedList<T>, содержащий элементы, ско­пированные из указанного класса IEnumera­ble, и обладающий емкостью, достаточной
для того, чтобы вместить количество скопи­рованных элементов.
56
Свойства Назначение
Count Обеспечивает доступ к числу узлов, которое в действительности
хранится в LinkedList<T> First Обеспечивает доступ к первому узелу объекта LinkedList<T> Last Обеспечивает доступ к последнему узелу объекта LinkedList<T>
Коллекция LinkedList<T> представляет отдельные узлы типа
LinkedListNode<T>, поэтому операции вставки и удаления являются
операциями с временной сложностью O(1).
Можно удалить узлы и повторно вставить их либо в тот же список, либо в другой список, что приведет к тому, что в куче не будут выде­лены дополнительные объекты. Так как список хранит внутреннее ко
-
личество узлов, получение этого значения через свойство Count явля­ется операцией O(1).
Списки, содержащие ссылочные типы, работают лучше, когда узел и его значение создаются одновременно. LinkedList<T> принимает null как допустимое свойство Value для ссылочных типов и допускает дуб­лирование значений. Если список пуст, свойства First и Last содержат
null.
В следующем примере создается двусвязный список LinkedList< City>
и инициализируется с помощью конструктора без параметров.
В список добавляются объекты класса City методами Add, AddLast,
AddFirst, затем в него добавляются два объекта с помощью методов AddBefore, AddAfter, и элементы списка выводятся на консоль. Выво-
дится число элементов в списке и максимальный элемент. Затем выво­дятся элементы списка, отфильтрованные методом Where с предика­том, заданным лямбда-выражением
(см. раздел Лямбда-выражения). С помощью метода Reverse создается объект запроса, с помощью ко­торого можно получить доступ к элементам списка в обратном поряд­ке, и список выводится в обратном порядке.
В классе City описаны поля для хранения названий городов (Name) и численность населения в тысячах человек (Pop). В нем реализованы интерфейсы IComparable<City>, IComparer<City> (см. раздел
Интер­фейсы), которые обеспечивают возможность упорядочения объектов. Переопределен метод Equals, который обеспечивает поиск объектов в списке. Сравнение и упорядочение объектов осуществляются по полю Pop.
57
classCity:IComparable<City>,IComparer<City> { publicstringName{get;} publicintPop{get;}  publicCity(stringn,intp) { Name=n; Pop=p; } publicoverridestringToString() { return$"{Name,18},\t{Pop}"; } //КомпаратордляупорядоченияобъектовCity. public { if(x.Pop<y.Pop) { return‐1; } else { if(x.Pop==y.Pop)return0; elsereturn1; } } //КомпаратордляупорядоченияобъектовCity. publicintCompareTo(Cityx) { returnCompare(this,x); }  //СравнениеобъектовCityнаравенство. publicoverrideboolEquals(objectobj) { if(this==null&obj==null)returntrue; elseif(this!=null&obj==null|this==null&obj!=null)returnfalse; return(objasCity).CompareTo(this)==0; } }  classProgram
intCompare(Cityx,Cityy)
58
{ staticvoidMain(string[]args) { //Создаемпустойсписок. LinkedList<City>cities=newLinkedList<City>(); //ДобавляемвсписокэлементыметодамиAdd,AddLast,AddFirst,AddBefore. cities.AddLast(newCity("Екатеринбург",1493)); cities.AddLast(newCity("НижнийНовгород",1252)); cities.AddLast(newCity("Казань",1257)); cities.AddFirst(newCity("Челябинск",1196)); cities.AddLast(newCity("Омск",1154)); //ДобавляемвсписокэлементыметодамиAddBefore,AddAfter. LinkedListNode<City>node= cities.AddBefore(node,newCity("Уфа",1125)); //ДобавляемвсписокэлементыметодамиAddBefore,AddAfter. LinkedListNode<City>cur=cities.Find(newCity("",1196)); cities.AddAfter(cur,newCity("Новосибирск",1625)); //Выводимсписокнаконсоль. foreach(varelincities)Console.WriteLine(el); Console.WriteLine($"Макс.числ.={cities.Max()},элементов={cities.Count}"); //Фильтруемколлекциюнаосновепредиката,заданноголябда‐выражением. //ВыделяемгороданабуквуН,ивыводимнаконсоль. Console.WriteLine("Отфильтрованныйсписок:");
foreach(varelincities.Where(p=>p.Name[0]=='Н'))Console.WriteLine(el);
 //Формируемколлекциюэлементов,переставленныхвобратномпорядке //ивыводимнаконсоль. IEnumerable<City>fil=cities.Reverse(); Console.WriteLine("Списоквобратномпорядке:"); foreach(varelinfil)Console.WriteLine(el); } } Результатработыпрограммы: Челябинск,1196 Новосибирск,1625 Екатеринбург,1493 НижнийНовгород,1252 Уфа,1125 Казань,1257 Омск, Макс.числ.=Новосибирск,1625,элементов=7 Отфильтрованныйсписок: Новосибирск,1625 НижнийНовгород,1252
1154
cities.Find(newCity("",1257));
59
Списоквобратномпорядке: Омск,1154 Казань,1257 Уфа,1125 НижнийНовгород,1252 Екатеринбург,1493 Новосибирск,1625 Челябинск,1196
В следующем примере создается двусвязный список
LinkedList<City> и инициализируется с помощью конструктора, в ко-
торый в качестве параметра передается массив объектов класса City. Список выводится на консоль. Затем список сортируется по полю Name в порядке возрастания с помощью метода OrderBy и лямбда­выражения, элементы списка выводятся на консоль. После этого спи­сок сортируется по
полю Pop в порядке убывания с помощью метода
OrderByDescending и лямбда-выражения и элементы списка выводятся
на консоль. Затем с помощью метода Sum и лямбда-выражения под­считывается и выводится на консоль суммарная численность населе­ния городов, занесенных в список.
publicclassCity:IComparable<City>,IComparer<City> { publicstringName{get;} publicintPop{get;}  publicCity(stringn,intp) { Name=n; Pop=p; } publicoverridestringToString() { return$"{Name,18},\t{Pop}"; } publicint {  //СравнениеобъектовCity. if(x.Pop<y.Pop) { return‐1;
Compare(Cityx,Cityy)
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]