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

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

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
} else { if(x.Pop==y.Pop)return0; elsereturn1; } } publicintCompareTo(Cityx) { //СравнениеобъектовCity.  returnCompare(this,x); } publicoverrideboolEquals(objectobj) { if(this==null&obj==null)returntrue; else return(objasCity).CompareTo(this)==0; } }  staticvoidMain(string[]args) { City[]towns= { newCity("Москва",12678), newCity("Санкт‐Петербург",5398), newCity("Новосибирск",1625), new newCity("НижнийНовгород",1252), newCity("Казань",1257), newCity("Челябинск",1196), newCity("Омск",1154) }; LinkedList<City>cities=newLinkedList<City>(towns); Console.WriteLine("Исходныйсписок:"); foreach(varelincities)Console.WriteLine(el);  IEnumerable<City>cur=cities.OrderBy(x=>x.Name); Console.WriteLine("Список сортированный по полю Nameвпорядке возрастания:"); foreach(var
if(this!=null&obj==null|this==null&obj!=null)returnfalse;
City("Екатеринбург",1493),
elincur)Console.WriteLine(el);
61
 cur=cities.OrderByDescending(x=>x.Pop); Console.WriteLine("СписоксортированныйпополюPopвпорядкеубывания:"); foreach(varelincur)Console.WriteLine(el);  intsum=cities.Sum(x=>x.Pop); Console.WriteLine($"Суммарная численность населения в городах списка = {sum}"); } } }  Результатработыпримера: Исходныйсписок: Москва,12678 Санкт‐Петербург,5398 Новосибирск,1625 Екатеринбург,1493 НижнийНовгород,1252 Казань,1257 Челябинск,1196 Омск,1154 СписоксортированныйпополюNameвпорядкевозрастания: Екатеринбург,1493 Казань,1257 Москва,12678 НижнийНовгород,1252 Новосибирск,1625 Омск,1154 Санкт‐Петербург,5398 Челябинск,1196 СписоксортированныйпополюPopвпорядкеубывания: Москва,12678 Санкт‐Петербург,5398 Новосибирск,1625 Екатеринбург,1493 Казань,1257 НижнийНовгород,1252 Челябинск,1196 Омск,1154 Суммарнаячисленностьнаселениявгородахсписка=26053
62
УНИВЕРСАЛЬНЫЕ МНОЖЕСТВА –
КОЛЛЕКЦИИ HASHSET<T> И SORTEDSET<T>
Коллекция, содержащая только отличающиеся элементы, называ­ется множеством (set). В составе С# имеются два множества: HashSet<T> и SortedSet<T>. Оба они реализуют интерфейс ISet<T>. Коллекция HashSet<T> содержит неупорядоченное множество разли­чающихся элементов, а в SortedSet<T> элементы упорядочены.
Интерфейс ISet<T> (см. Интерфейсы) предоставляет методы для создания объединения нескольких множеств, пересечения множеств и определения, является ли
одно множество надмножеством или под­множеством другого. В следующей таблице перечислены операции и их математические эквиваленты.
Операция Математический эквивалент
UnionWith Объединение наборов IntersectWith Пересечение наборов ExceptWith Вычитание наборов SymmetricExceptWith Симметричное различие (включает элементы, принад-
лежащие только одному и только второму набору)
Помимо перечисленных операций над наборами класс HashSet<T> и SortedSet<T> предоставляет также методы для определения равен­ства наборов, перекрытия наборов и того, является ли набор подмно­жеством или надмножеством другого набора.
КОЛЛЕКЦИЯ HASHSET<T> – НЕУПОРЯДОЧЕННОЕ МНОЖЕСТВО
Объект класса HashSet<T> представляет неупорядоченное множе­ство значений типа Т. Здесь Т – тип элементов в коллекции. Класс
HashSet<T> реализует следующие интерфейсы:
ICollection<T>, IEnumerable<T>, IReadOnlyCollection<T>, IEnume­rable, ISet<T>, IDeserializationCallback, ISerializable.
Объекты класса HashSet<T> обеспечивают высокопроизводитель­ные операции с наборами. Набор – это коллекция, не содержащая по­вторяющихся элементов, элементы которой не имеют определенного порядка.
63
Ниже перечислены наиболее употребляемые конструкторы класса HashSet<T>:
publicHashSet() publicHashSet(IEnumerable<T>collection) publicHashSet(IEqualityComparecomparer) publicHashSet(IEnumerable<T>collection,IEqualityComparecomparer)
В первой форме конструктора создается пустое множество, а во второй форме – множество, состоящее из элементов указываемой кол­лекции collection. В третьей форме конструктора допускается указы­вать способ сравнения с помощью параметра comparer. В четвертой форме создается множество, состоящее из элементов указываемой коллекции collection, и используется заданный способ сравнения
comparer.
В этом классе предоставляется также
метод RemoveWhere(), уда-
ляющий из множества элементы, удовлетворяющие заданному усло­вию или предикату. Помимо свойств, определенных в интерфейсах, которые реализуются в классе HashSet<T>, в него введено дополни­тельное свойство Comparer, приведенное ниже:
publicIEqualityComparer<T>Comparer{get;}
Оно позволяет получать метод сравнения вызывающего хеш-мно­жества.
В следующем примере показано, как объединить два разнородных набора значений типа int. В примере создается два объекта evenNumbers, oddNumbers класса HashSet<T> и заполняются четными и нечетными числами соответственно. Третий объект numbers типа HashSet<T> создается из набора, содержащего четные числа. Затем с помощью метода UnionWith к numbers добавляется oddNumbers.
usingSystem; usingSystem.Collections.Generic;
namespaceExample_1 {
classProgram { staticvoidMain(string[]args) {
64
HashSet<int>evenNumbers=newHashSet<int>(); HashSet<int>oddNumbers=newHashSet<int>(); for(inti=0;i<5;i++) { //Заполняеммножествотолькочетнымичислами. evenNumbers.Add(i*2); //Заполняеммножествотольконечетнымичислами. oddNumbers.Add((i*2)+1); } Console.Write($"evenNumbersсодержит{evenNumbers.Count}элементов:"); DisplaySet(evenNumbers); Console.Write($"oddNumbersсодержит{oddNumbers.Count}элементов:"); DisplaySet(oddNumbers); 
//СоздаемновыйHashSetзаполненныечетнымичислами. HashSet<int>numbers=newHashSet<int>(evenNumbers); Console.WriteLine("numbersобъединяемсoddNumbers..."); numbers.UnionWith(oddNumbers); Console.Write($"numbersсодержит{numbers.Count}элементов:"); DisplaySet(numbers); } staticvoidDisplaySet(HashSet<int>collection) { Console.Write("{"); foreach(intiincollection) { Console.Write($"{i}"); } Console.WriteLine("}"); } } }  Результатработыпримера:
evenNumbersсодержит5элементов:{ oddNumbersсодержит5элементов:{13579} numbersобъединяемсoddNumbers... numbersсодержит10элементов:{0246813579}
02468}
В следующем примере показано, как работать с множеством HashSet<T> объектов класса Box. Создаются два объекта HashSet<Box> c разными функциями для сравнения и хэширования объектов класса Box. Они описаны в двух классах BoxEqualityComparer
65
и BoxEquality Comparer1, реализующих интерфейс IEqualityComparer <Box>. В коллекцию добавляются объекты методом Add и удаляются
методом RemoveWhere по условию, заданному лямбда-выражением (см. раздел Лямбда-выржения), затем элементы коллекции выводятся на консоль. Попытка добавления дублирующего элемента игнорируется.
publicclassBox { publicBox(inth,intl,intw) { this.Height=h;//Высрта. this.Length=l;//Длина. this.Width=w;//Ширина. } publicintHeight{get;set;} publicintLength{get;set;} publicintWidth{get;set;} publicintVolume{get{returnHeight*Length*Width;}} publicoverrideStringToString() { returnString.Format($"({Height},{Length},{Width})"); } } //Класс,реализующийфункциюEqualsинтерфейсаIEqualityComparer, //обеспечивающуюпроверкуобъектовBoxнаравенство. classBoxEqualityComparer1:IEqualityComparer<Box> { publicboolEquals(Boxb1,Boxb2)
{ if(b2==null&&b1==null) returntrue; elseif(b1==null||b2==null) returnfalse; elseif(b1.Volume==b2.Volume) returntrue; else returnfalse; }  //Хэш‐функциядляпомещенияобъектавHashSet. publicintGetHashCode(Boxbx) { inthCode=bx.Volume;
66
returnhCode.GetHashCode(); } } //Класс,реализующийфункциюEqualsинтерфейсаIEqualityComparer, //обеспечивающуюпроверкуобъектовBoxнаравенство. classBoxEqualityComparer:IEqualityComparer<Box> { publicboolEquals(Boxb1,Boxb2) { if(b2==null&&b1==null) returntrue; elseif(b1==null||b2==null) returnfalse; elseif(b1.Height==b2.Height&&b1.Length==b2.Length &&b1.Width==b2.Width) returntrue; else returnfalse; } //Хэш‐функциядляпомещенияобъектавHashSet. publicintGetHashCode(Boxbx) { inthCode=bx.Height^bx.Length^bx.Width;; returnhCode.GetHashCode(); } }  
usingSystem; usingSystem.Collections.Generic;
namespaceExample_2 {
classProgram { staticvoidMain(string[]args) { HashSet<Box>boxes=newHashSet<Box>(newBoxEqualityComparer()) { newBox(1,2,3), newBox(2,4,3), newBox(5,2,6), };
67
boxes.Add(newBox(4,2,7)); boxes.Add(newBox(1,1,6)); Display(boxes); intc=boxes.RemoveWhere(b=>b.Volume<30); Console.WriteLine($"Удалено‐{c}элементов."); Display(boxes); varbox=newHashSet<Box>(boxes,newBoxEqualityComparer1()); if(!box.Add(newBox(2,5,6))) Console.WriteLine($"ЭлементстакимзначниемVolumeвомножествеесть."); Display(box); } staticvoidDisplay(IEnumerable<Box>x) { Console.Write("{"); foreach(varel Console.Write(el.ToString()); Console.WriteLine("}"); } } }  Результатработыпримера: {(1,2,3)(2,4,3)(5,2,6)(4,2,7)(1,1,6)} Удалено‐3элементов. {(5,2,6)(4,2,7)} ЭлементстакимзначениемVolumeвомножествеесть.
{(5,2,6)(4,2,7)}
inx)
УПОРЯДОЧЕННОЕ МНОЖЕСТВО – КЛАСС SORTEDSET<T>
Коллекция SortedSet<T> представляет упорядоченное множество. Здесь T – тип объектов коллекции. Объект класса SortedSet<T> под­держивает коллекцию в сортированном порядке. Дублирующиеся эле­менты в коллекции не допускаются. Изменение значений элементов коллекции не поддерживается.
Ниже перечислены четыре наиболее часто используемых конструк­тора, определенных в классе SortedSet<T>:
publicSortedSet() publicSortedSet(IEnumerable<T>collection) publicSortedSet(IComparercomparer) publicSortedSet(IEnumerable<T>collection,IComparercomparer)
68
В первой форме конструктора создается пустое множество, а во второй форме – множество, состоящее из элементов указываемой кол­лекции collection. В третьей форме конструктора допускается указы­вать способ сравнения с помощью параметра comparer. В четвертой форме создается множество, состоящее из элементов указываемой коллекции collection, и используется заданный способ сравнения
comparer.
Упорядоченное множество предоставляет метод GetViewBetween(), возвращающий часть множества как объект типа SortedSet<T>, метод RemoveWhere(), удаляющий из множества элементы, удовлетворяющие заданному условию, или предикату (см. раздел Делегат Predicate), а также метод Reverse(), возвращающий объект типа IEnumerable<T>, который позволяет циклически получить доступ к элементам множе­ства в обратном порядке.
Помимо свойств, определенных в интерфейсах (см. раздел Интер­фейсы), которые реализуются в дополнительные свойства, приведенные ниже:
publicIComparer<T>Comparer{get;}
publicTMax{get;}
publicTMin{get;}
классе SortedSet<T>, в нем имеются
Свойство Comparer обеспечивает доступ к способу сравнения для вызывающего множества. Свойство Мах обеспечивает доступ к наибольшему значению во множестве, а свойство Min – к наимень­шему значению во множестве.
В следующем примере создается и инициализируется объект set класса SortedSet<T> с помощью конструктора без параметров. При со­здании set инициализируется тремя объектами класса Record, затем в него добавляются
два объекта с помощью метода Add и элементы множества выводятся на консоль. Затем предпринимается попытка до­бавить в множество имеющийся элемент. Выводится число элементов, минимальный и максимальный элементы множества. С помощью функции Reverse элементы множества просматриваются в обратном порядке. С помощью функции Count и лямбда-выражения (см. раздел Лямбда-выражения) подсчитывается число элементов со
свойством, заданным лямбда-выражением. С помощью функции TakeWhile и лямбда-выражения выводятся на консоль элементы со свойством, за­данным лямбда-выражением.
69
Класс Record содержит два автоматически распределяемых свой­ства типа double и реализует интерфейсы IComparable<Record>, IComparer<Record>, которые обеспечивают компараторы для сравне­ния на равенство и упорядочения объектов. В нем переопределен ме­тод ToString().
publicclassRecord:IComparable<Record>,IComparer<Record> { publicdoublere{get;} publicdoubleim{get;}  publicRecord(doubler,doublei) { re=r;im=i; } publicdoubleModule() { returnMath.Sqrt(re*re+im*im); 
} //СравнениеобъектовRecord. publicintCompare(Recordx,Recordy) { if(x.Module()<y.Module()) { return‐1; } else { if(x.Module()==y.Module())return0; elsereturn1; } } //СравнениеобъектовRecord. publicintCompareTo(Recordx) { returnCompare(this,x); }
publicoverridestringToString() { return$"({re.ToString()},{im.ToString()})"; } }
70
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]