Коллекции
Рассмотрим несколько примеров использования динамического массива.
using System; using System.Collections; namespace MyProgram { class Program { static void ArrayPrint(string s, ArrayList a) { Console.WriteLine(s); foreach (int i in a) Console.Write(i + " "); Console.WriteLine(); } static void Main(string[] args) { ArrayList myArray = new ArrayList(); Console.WriteLine("Начальная емкость массива: " + myArray.Capacity); Console.WriteLine("Начальное количество элементов: " + myArray.Count); Console.WriteLine("\nДобавили 5 цифр"); for (int i = 0; i < 5; i++) myArray.Add(i); Console.WriteLine("Текущая емкость массива: " + myArray.Capacity); Console.WriteLine("Текущее количество элементов: " + myArray.Count); ArrayPrint("Содержимое массива", myArray); Console.WriteLine("\nОптимизируем емкость массива"); myArray.Capacity=myArray.Count; Console.WriteLine("Текущая емкость массива: " + myArray.Capacity); Console.WriteLine("Текущее количество элементов: " + myArray.Count); ArrayPrint("Содержимое массива", myArray); Console.WriteLine("\nДобавляем элементы в массив"); myArray.Add(10); myArray.Insert(1, 0); myArray.AddRange(myArray); Console.WriteLine("Текущая емкость массива: " + myArray.Capacity); Console.WriteLine("Текущее количество элементов: " + myArray.Count); ArrayPrint("Содержимое массива", myArray); Console.WriteLine("\nУдаляем элементы из массива"); myArray.Remove(0); myArray.RemoveAt(10); Console.WriteLine("Текущая емкость массива: " + myArray.Capacity); Console.WriteLine("Текущее количество элементов: " + myArray.Count); ArrayPrint("Содержимое массива", myArray); Console.WriteLine("\nУдаляем весь массив"); myArray.Clear(); Console.WriteLine("Текущая емкость массива: " + myArray.Capacity); Console.WriteLine("Текущее количество элементов: " + myArray.Count); ArrayPrint("Содержимое массива", myArray); } } }
Пример 2.В текстовом файле записана информация о людях (фамилия, имя, отчество, возраст, вес через пробел). Вывести на экран информацию о людях, отсортированную по возрасту.
using System; using System.Collections; using System.IO; using System.Text; namespace MyProgram { class Program { public struct one //структура для хранения данных об одном человеке { public string f; public string i; public string o; public int age; public float massa; } public class SortByAge : IComparer //реализация стандартного интерфейса { int IComparer.Compare(object x, object y) //переопределение метода Compare { one t1 = (one)x; one t2 = (one)y; if (t1.age > t2.age) return 1; if (t1.age < t2.age) return -1; return 0; } } static void ArrayPrint(string s, ArrayList a) { Console.WriteLine(s); foreach (one x in a) Console.WriteLine(x.f + "\t"+ x.i + "\t"+ x.o + "\t"+x.age + "\t" + x.massa); } static void Main(string[] args) { StreamReader fileIn = new StreamReader("t.txt",Encoding.GetEncoding(1251)); string line; one a; ArrayList people = new ArrayList(); string[] temp = new string[5]; while ((line=fileIn.ReadLine())!=null) //цикл для организации обработки файла { temp = line.Split(' '); a.f = temp[0]; a.i = temp[1]; a.o = temp[2]; a.age = int.Parse(temp[3]); a.massa = float.Parse(temp[4]); people.Add(a); } fileIn.Close(); ArrayPrint("Исходные данные: ", people); people.Sort(new Program.SortByAge()); //вызов сортировки ArrayPrint("Отсортированные данные: ", people); } } } ______________t.txt________________ Иванов Сергей Николаевич 21 64 Петров Игорь Юрьевич 45 88 Семёнов Михаил Алексеевич 20 70 Пиманов Александр Дмитриевич 53 101
Класс Hashtable
Класс Hashtable предназначен для создания коллекции, в которой для хранения объектов используется хеш-таблица. В хеш-таблице для хранения информации используется механизм, именуемый хешированием (hashing). Суть хеширования состоит в том, что для определения уникального значения, которое называется хеш-кодом, используется информационное содержимое соответствующего ему ключа. Хеш-код затем используется в качестве индекса, по которому в таблице отыскиваются данные, соответствующие этому ключу. Преобразование ключа в хеш-код выполняется автоматически, т.е. сам хеш-код вы даже не увидите. Но преимущество хеширования - в том, что оно позволяет сокращать время выполнения таких операций, как поиск, считывание и запись данных, даже для больших объемов информации.
Класс Hashtable реализует стандартные интерфейсы IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback и ICloneable. Размер хеш-таблицы может динамически изменяться. Размер таблицы увеличивается тогда, когда количество элементов превышает значение, равное произведению вместимости таблицы и ее коэффициента заполнения, который может принимать значение на интервале от 0,1 до 1,0. По умолчанию установлен коэффициент равный 1,0.
В классе Hashtable определено несколько конструкторов:
public Hashtable() //создает пустую хеш-таблицу // строит хеш-таблицу, которая инициализируется элементами коллекции с public Hashtable(IDictionary с) public Hashtable(int capacity) //создает хеш-таблицу с вместимостью capacity //создает хеш-таблицу вместимостью capacity и коэффициентом заполнения n public Hashtable(int capacity, float n)
Помимо методов, определенных в интерфейсах, которые реализует класс Hashtable, в нем определены и собственные методы:
Метод | Описание |
---|---|
public virtual bool ContainsKey (object k) | Возвращает значение true , если в вызывающей хеш-таблице содержится ключ, заданный параметром k. В противном случае возвращает значение false |
public virtual bool ContainsValue (object v) | Возвращает значение true, если в вызывающей хеш-таблице содержится значение, заданное параметром v. В противном случае возвращает значение false |
public virtual IDictionaryEnumerator GetEnumerator() | Возвращает для вызывающей хеш-таблицы нумератор типа IDictionaryEnumerator |
В классе Hashtable, помимо свойств, определенных в реализованных им интерфейсах, определены два собственных public -свойства:
public virtual ICollection Keys { get; } //позволяет получить коллекцию ключей public virtual ICollection Values { get; } //позволяет получить коллекцию значений
Для добавления элемента в хеш-таблицу необходимо вызвать метод Add(), который принимает два отдельных аргумента: ключ и значение. Важно отметить, что хеш-таблица не гарантирует сохранения порядка элементов, т.к хеширование обычно не применяется к отсортированным таблицам.
Рассмотрим пример, который демонстрирует использование Hashtable коллекции:
Пример 1:рассмотрим простые операции с хеш-таблицей
using System; using System.Collections; namespace MyProgram { class Program { static void printTab(string s, Hashtable a) { Console.WriteLine(s); ICollection key = a.Keys; //Прочитали все ключи foreach (string i in key)//использование ключа для получения значения { Console.WriteLine(i+"\t"+a[i]); } Console.WriteLine(); } static void Main(string[] args) { Hashtable tab = new Hashtable(); Console.WriteLine("Начальное количество элементов: " + tab.Count); printTab("Содержимое таблицы: ", tab); Console.WriteLine("Добавили в таблицу записи"); tab.Add("001","ПЕРВЫЙ"); tab.Add("002","ВТОРОЙ"); tab.Add("003","ТРЕТИЙ"); tab.Add("004", "ЧЕТВЕРТЫЙ"); tab.Add("005", "ПЯТЫЙ"); Console.WriteLine("Текущее количество элементов: " + tab.Count); printTab("Содержимое заполненной таблицы", tab); tab["005"] = "НОВЫЙ ПЯТЫЙ"; tab["001"] = "НОВЫЙ ПЕРВЫЙ"; printTab("Содержимое измененной таблицы", tab); } } }
Пример 2. Разработаем простейшую записную книжку, в которую можно добавлять и удалять телефоны, а также осуществлять поиск номера телефона по фамилии и фамилии по номеру телефона.
using System; using System.Collections; using System.IO; using System.Text; namespace MyProgram { class Program { static void printTab(string s, Hashtable a) { Console.WriteLine(s); ICollection key = a.Keys; //Прочитали все ключи foreach (string i in key)//использование ключа для получения значения { Console.WriteLine(i + "\t" + a[i]); } } static void Main(string[] args) { StreamReader fileIn = new StreamReader("t.txt",Encoding.GetEncoding(1251)); string line; Hashtable people = new Hashtable(); while ((line = fileIn.ReadLine()) != null) //цикл для организации обработки файла { string [] temp = line.Split(' '); people.Add(temp[0],temp[1]); } fileIn.Close(); printTab("Исходные данные: ", people); Console.WriteLine("Введите номер телефона"); line = Console.ReadLine(); if (people.ContainsKey(line)) Console.WriteLine(line + "\t" + people[line]); else { Console.WriteLine("Такого номера нет в записной книжке.\nВведите фамилию: "); string line2=Console.ReadLine(); people.Add(line,line2); } printTab("Исходные данные: ", people); Console.WriteLine("Введите фамилию для удаления"); line = Console.ReadLine(); if (people.ContainsValue(line)) { ICollection key =people.Keys; //Прочитали все ключи Console.WriteLine(line); string del=""; foreach (string i in key)//использование ключа для получения значения if (string.Compare((string)people[i], line) == 0) { del = i; break; } Console.WriteLine(del + "\t" + people[del] + "- данные удалены!!!"); people.Remove(del); printTab("Измененные данные: ", people); } else Console.WriteLine("Такого абонента в записной книжке нет "); } } } _________t.txt____________ 12-34-56 Иванов 78-90-12 Петров 34-56-78 Семёнов 90-11-12 Пиманов