программирование. Руководство su P# a n Reference в herbert schildt полное руководство с 0 герберт шилдт
Скачать 3.32 Mb.
|
ToArray() зывающего объекта public virtual Array Возвращает массив, содержащий копии элементов вы ToArray(Type type) зывающего объекта. Тип элементов этого массива определяется параметром type public virtual void Устанавливает значение свойства Capacity равным TrimToSize() значению свойства Count В классе ArrayList поддерживается также ряд методов, оперирующих элементами коллекции в заданных пределах. Так, в одну коллекцию типа ArrayList можно вставить другую коллекцию, вызвав метод InsertRange (). Для удаления из коллекции элементов в заданных пределах достаточно вызвать метод RemoveRange (). А для перезаписи элементов коллекции типа ArrayList в заданных пределах элементами из другой коллекции служит метод Set Range () . И наконец, элементы коллекции можно сортировать или искать в заданных пределах, а не во всей коллекции. По умолчанию коллекция типа ArrayList не синхронизирована. Для получения синхронизированной оболочки, в которую заключается коллекция, вызывается метод Synchronized(). В классе ArrayList имеется также приведенное ниже свойство Capacity, помимо свойств, определенных в интерфейсах, которые в нем реализуются. public virtual int Capacity { get; set; } Свойство Capacity позволяет получать и устанавливать емкость вызывающей коллекции типа ArrayList. Емкость обозначает количество элементов, которые может содержать коллекция типа ArrayList до ее вынужденного расширения. Как упоминалось выше, коллекция типа ArrayList расширяется автоматически, и поэтому задавать ее емкость вручную необязательно. Но из соображений эффективности это иногда можно сделать, если количество элементов коллекции известно заранее. Благодаря этому исключаются издержки на выделение дополнительной памяти. С другой стороны, если требуется сократить размер базового массива коллекции типа ArrayList, то для этой цели достаточно установить меньшее значение свойства Capacity. Но это значение не должно быть меньше значения свойства Count. Напомним, что свойство Count определено в интерфейсе ICollection и содержит количество объектов, хранящихся в коллекции на данный момент. Всякая попытка установить значение свойства Capacity меньше значения свойства Count приводит к генерированию исключения ArgumentOutOfRangeException. Поэтому для получения такого количества элементов коллекции типа ArrayList, которое содержится в ней на данный момент, следует установить значение свойства Capacity равным значению свойства Count. Для этой цели можно также вызвать метод TrimToSize (). В приведенном ниже примере программы демонстрируется применение класса ArrayList. В ней сначала создается коллекция типа ArrayList, а затем в эту коллекцию вводятся символы, после чего содержимое коллекции отображается. Некоторые элементы затем удаляются из коллекции, и ее содержимое отображается вновь. После этого в коллекцию вводятся дополнительные элементы, что вынуждает увеличить ее емкость. И наконец, содержимое элементов коллекции изменяется. // Продемонстрировать применение класса ArrayList. using System; using System.Collections; class ArrayListDemo { static void Main() { // Создать коллекцию в виде динамического массива. ArrayList al = new ArrayList (); Console.WriteLine("Исходное количество элементов: " + al.Count); Console.WriteLine(); Console.WriteLine("Добавить 6 элементов"); // Добавить элементы в динамический массив. al.Add('С'); al.Add('А'); al.Add('E') ; al.Add(1В1) ; al.Add('D') ; al.Add(1F') ; Console.WriteLine("Количество элементов: " + al.Count); // Отобразить содержимое динамического массива, // используя индексирование массива. Console.Write("Текущее содержимое: "); for(int i=0; i < al.Count; i++) Console.Write (al[i] + " "); Console.WriteLine("\n"); Console.WriteLine("Удалить 2 элемента"); // Удалить элементы из динамического массива, al.Remove('F'); al.Remove('A'); Console.WriteLine("Количество элементов: " + al.Count); // Отобразить содержимое динамического массива, используя цикл foreach. Console.Write("Содержимое: "); foreach(char с in al) Console.Write(с + " "); Console.WriteLine("\n"); Console.WriteLine("Добавить еще 20 элементов"); // Добавить количество элементов, достаточное для // принудительного расширения массива, for (int i=0; i < 20; i++) al.Add((char)('a' + i)); Console.WriteLine("Текущая емкость: " + al.Capacity); Console.WriteLine("Количество элементов после добавления 20 новых: " + al.Count); Console.Write("Содержимое: "); foreach(char с in al) Console.Write(с + " "); Console.WriteLine("\n"); // Изменить содержимое динамического массива, // используя индексирование массива. Console.WriteLine("Изменить три первых элемента"); al [0] = 1X1 ; al[1] = 'Y'; al[2] = 'Z'; Console.Write("Содержимое: "); foreach(char с in al) Console.Write (c + " "); Console.WriteLine (); Вот к какому результату приводит выполнение этой программы. Исходное количество элементов: О Добавить 6 элементов Количество элементов: 6 Текущее содержимое: С А Е В D F Удалить 2 элемента Количество элементов: 4 Содержимое: С Е В D Добавить еще 20 элементов Текущая емкость: 32 Количество элементов после добавления 20 новых: 24 Содержимое: CEBDabcdefghij klmnopqrst Изменить три первых элемента Содержимое: XYZDabcdefghij klmnopqrst Сортировка и поиск в коллекции типа ArrayList Коллекцию типа ArrayList можно отсортировать с помощью метода Sort (). В этом случае поиск в отсортированной коллекции с помощью метода BinarySearch () становится еще более эффективным. Применение обоих методов демонстрируется в приведенном ниже примере программы. // Отсортировать коллекцию типа ArrayList и осуществить в ней поиск. using System; using System.Collections; class SortSearchDemo { static void Main() { // Создать коллекцию в виде динамического массива. ArrayList al = new ArrayList(); // Добавить элементы в динамический массив. al.Add(55); al.Add(43) ; al.Add(‑4); al.Add(88); al.Add(3); al.Add(19) ; Console.Write("Исходное содержимое: "); foreach(int i in al) Console.Write (i + " "); Console.WriteLine ("\n"); // Отсортировать динамический массив, al.Sort(); // Отобразить содержимое динамического массива, используя цикл foreach. Console..Write ("Содержимое после сортировки: ") ; foreach (int i in al) Console.Write (i + " "); Console.WriteLine ("\n"); Console.WriteLine("Индекс элемента 43: " + al.BinarySearch (43)); } } Ниже приведен результат выполнения этой программы. Исходное содержимое: 55 43 ‑488 3 19 Содержимое после сортировки: ‑4 3 19 43 55 88 Индекс элемента 43: 3 В одной и той же коллекции типа ArrayList могут храниться объекты любого типа. Тем не менее во время сортировки и поиска в ней эти объекты приходится сравнивать. Так, если бы список объектов в приведенном выше примере программы содержал символьную строку, то их сравнение привело бы к исключительной ситуации. Впрочем, для сравнения символьных строк и целых чисел можно создать специальные методы. О таких методах сравнения речь пойдет далее в этой главе. Получение массива из коллекции типа ArrayList В работе с коллекцией типа ArrayList иногда требуется получить из ее содержимого обычный массив. Этой цели служит метод ТоАггау (). Для преобразования коллекции в массив имеется несколько причин. Две из них таковы: потребность в ускорении обработки при выполнении некоторых операций и необходимость передавать массив методу, который не перегружается, чтобы принять коллекцию. Но независимо от конкретной причины коллекция типа ArrayList преобразуется в обычный^лассив довольно просто, как показано в приведенном ниже примере программы. // Преобразовать коллекцию типа ArrayList в обычный массив. using System; using System.Collections; class ArrayListToArray { static void Main() { ArrayList al = new ArrayList(); // Добавить элементы в динамический массив, al.Add(1); al.Add(2); al.Add(3) ; al.Add(4) ; Console.Write("Содержимое: "); foreach(int i in al) Console.Write(i + " "); Console.WriteLine(); int[] ia = (int[]) al.ToArray(typeof(int)); int sum = 0; // Просуммировать элементы массива, for(int i=0; icia.Length; i++) sum += ia[i]; Console.WriteLine("Сумма равна: " + sum); } } Эта программа дает следующий результат. Содержимое: 1 2 3 4 Сумма равна: 10 В начале этой программы создается коллекция целых чисел. Затем в ней вызывается метод ToArray () с указанием типа int получаемого массива. В итоге создается целочисленный массив. Но поскольку Array является типом, возвращаемым методом ToArray () , то содержимое получаемого в итоге массива должно быть приведено к типу int [ ]. (Напомним, что Array является базовым типом для всех массивов в С#.) И наконец, значения всех элементов массива суммируются. Класс Hashtable Класс Hashtable предназначен для создания коллекции, в которой для хранения ее элементов служит хеш‑таблица. Как должно быть известно большинству читателей, информация сохраняется в хеш‑таблице с помощью механизма, называемого хешированием. При хешировании для определения уникального значения, называемого хеш‑кодом , используется информационное содержимое специального ключа. Полученный в итоге хеш‑код служит в качестве индекса, по которому в таблице хранятся искомые данные, соответствующие заданному ключу. Преобразование ключа в хеш‑код выполняется автоматически, и поэтому сам хеш‑код вообще недоступен пользователю. Преимущество хеширования заключается в том, что оно обеспечивает постоянство времени выполнения операций поиска, извлечения и установки значений независимо от величины массивов данных. В классе Hashtable реализуются интерфейсы I Dictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback и ICloneable. В классе Hashtable определено немало конструкторов. Ниже приведены наиболее часто используемые конструкторы этого класса. public Hashtable () public Hashtable(IDictionary d) public Hashtable(int capacity) public Hashtable(int capacity, float loadFactor) В первой форме создается создаваемый по умолчанию объект класса Hashtable. Во второй форме создаваемый объект типа Hashtable инициализируется элементами из коллекции d. В третьей форме создаваемый объект типа Hashtable инициализируется, учитывая емкость коллекции, задаваемую параметром capacity. И в четвертой форме создаваемый объект типа Hashtable инициализируется, учитывая заданную емкость capacity и коэффициент заполнения loadFactor. Коэффициент заполнения, иногда еще называемый коэффициентом загрузки, должен находиться в пределах от ОД до 1,0. Он определяет степень заполнения хеш‑таблицы до увеличения ее размера. В частности, таблица расширяется, если количество элементов оказывается больше емкости таблицы, умноженной на коэффициент заполнения. В тех конструкторах, которые не принимают коэффициент заполнения в качестве параметра, этот коэффициент по умолчанию выбирается равным 1, 0. В классе Hashtable определяется ряд собственных методов, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются. Некоторые из наиболее часто используемых методов этого класса приведены в табл. 25.5. В частности, для того чтобы определить, содержится ли ключ в коллекции типа Hashtable, вызывается метод Contains Key (). А для того чтобы выяснить, хранится ли в такой коллекции конкретное значение, вызывается метод ContainsValue (). Для перечисления содержимого коллекции типа Hashtable служит метод GetEnumerator (), возвращающий объект типа IDictionaryEnumerator. Напомним, что IDictionaryEnumerator – это перечислитель, используемый для перечисления содержимого коллекции, в которой хранятся пары "ключ‑значение". Таблица 25.5. Наиболее часто используемые методы, определенные в классе Hashtable Метод Описание public virtual bool ContainsKey(object key) public virtual bool ContainsValue(object value) public virtual IDictionaryEnumerator GetEnumerator () public static Hashtable Synchronized(Hashtable table) Возвращает логическое значение true, если в вызывающей коллекции типа Hashtable содержится ключ key, а иначе – логическое значение false Возвращает логическое значение true, если в вызывающей коллекции типа Hashtable содержится значение value , а иначе – логическое значение false Возвращает для вызывающей коллекции типа Hashtable перечислитель типа IDictionaryEnumerator Возвращает синхронизированный вариант коллекции типа Hashtable, передаваемой в качестве параметра table В классе Hashtable доступны также открытые свойства, определенные в тех интерфейсах, которые в нем реализуются. Особая роль принадлежит двум свойствам, Keys и Values, поскольку с их помощью можно получить ключи или значения из коллекции типа Hashtable. Эти свойства определяются в интерфейсе IDictionary следующим образом. public virtual ICollection Keys { get; } public virtual ICollection Values { get; } В классе Hashtable не поддерживаются упорядоченные коллекции, и поэтому ключи или значения получаются из коллекции в произвольном порядке. Кроме того, в классе Hashtable имеется защищенное свойство EqualityComparer. А два других свойства, hep и comparer, считаются устаревшими. Пары "ключ‑значение" сохраняются в коллекции типа Hashtable в форме структуры типа DictionaryEntry, но чаще всего это делается без прямого вмешательства со стороны пользователя, поскольку свойства и методы оперируют ключами и значениями по отдельности. Если, например, в коллекцию типа Hashtable добавляется элемент, то для этой цели вызывается метод Add () , принимающий два аргумента: ключ и значение. Нужно, однако, иметь в виду, что сохранение порядка следования элементов в коллекции типа Hashtable не гарантируется. Дело в том, что процесс хеширования оказывается, как правило, непригодным для создания отсортированных таблиц. Ниже приведен пример программы, в которой демонстрируется применение класса Hashtable. // Продемонстрировать применение класса Hashtable. using System; using System.Collections; class HashtableDemo { static void Main() { // Создать хеш‑таблицу. Hashtable ht = new Hashtable (); // Добавить элементы в таблицу. ht.Add("здание", "жилое помещение"); ht.Add("автомашина", "транспортное средство"); ht.Add("книга", "набор печатных слов"); ht.Add("яблоко", "съедобный плод"); // Добавить элементы с помощью индексатора, ht ["трактор"] = "сельскохозяйственная машина"; // Получить коллекцию ключей. ICollection с = ht.Keys; // Использовать ключи для получения значений, foreach(string str in с) Console.WriteLine(str + ": " + ht[str]); } } Выполнение этой программы приводит к следующему результату. здание: жилое помещение книга: набор печатных слов трактор: сельскохозяйственная машина автомашина: транспортное средство яблоко: съедобный плод Как следует из приведенного выше результата, пары "ключ‑значение" сохраняются в произвольном порядке. Обратите внимание на то, как получено и отображено содержимое хеш‑таблицы ht. Сначала была получена коллекция ключей с помощью свойства Keys. Затем каждый ключ был использован для индексирования хеш‑таблицы ht с целью извлечь из нее значение, соответствующее заданному ключу. Напомним, что в качестве индекса в данном случае использовался индексатор, определенный в интерфейсе IDictionary и реализованный в классе Hashtable. Класс SortedList |