zoukankan      html  css  js  c++  java
  • C#4.0 Collections【集合】

    URI:http://www.albahari.com/nutshell/cs4ch07.aspx

    集合:

    Implementing IEnumerable<T> with an iterator(实现IEnumerable<T>的迭代器):

    public class MyGenCollection : IEnumerable<int>
    {
    int[] data = {1, 2, 3};

    public IEnumerator<int> GetEnumerator()
    {
    foreach (int i in data)
    yield return i;
    }

    IEnumerator IEnumerable.GetEnumerator() // Explicit implementation(显示实现IEnumerable<T>迭代器的接口)
    { // keeps it hidden.
    return GetEnumerator();
    }
    }

    Implementing IEnumerable<T> directly(直接显示实现IEnumerable<T>接口的好处):

    class MyIntList : IEnumerable<int>
    {
    int[] data = { 1, 2, 3 };

    // The generic enumerator is compatible with both IEnumerable and
    // IEnumerable<T>. We implement the nongeneric GetEnumerator method
    // explicitly to avoid a naming conflict.
    /*

    一个通用的枚举迭代器是需要兼容IEnumerable和IEnumerable<T>接口的,我们通过显示的方式实现GetEnumerator接口来避免接口命名(同名)冲突
    */

    public IEnumerator<int> GetEnumerator() { return new Enumerator(this); }
    IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(this); }

    class Enumerator : IEnumerator<int>
    {
    int currentIndex = -1;
    MyIntList collection;

    internal Enumerator (MyIntList collection)
    {
    this.collection = collection;
    }

    public int Current { get { return collection.data [currentIndex]; } }
    object IEnumerator.Current { get { return Current; } }

    public bool MoveNext()
    {
    return ++currentIndex < collection.data.Length;
    }

    public void Reset() { currentIndex = -1; }

    // Given we don’t need a Dispose method, it’s good practice to
    // implement it explicitly, so it’s hidden from the public interface.(由于我们不需要对外提供Dispose()方法,最好的方式就是通过显示实现接口的Dispose()方法。)

    void IDisposable.Dispose() {}
    }
    }

    Using List<T>(List<T>用例):

    List<string> words = new List<string>();    // New string-typed list

    words.Add ("melon");
    words.Add ("avocado");
    words.AddRange (new string[] { "banana", "plum" } );
    words.Insert (0, "lemon"); // insert at
    words.InsertRange (0, new string[] { "peach", "nashi" }); // start

    words.Remove ("melon");
    words.RemoveAt (3); // Remove the 4th element
    words.RemoveRange (0, 2); // Remove first 2 elements

    // Remove all strings starting in 'n':
    words.RemoveAll (delegate (string s) { return s.StartsWith ("n"); });

    Console.WriteLine (words [0]); // first word
    Console.WriteLine (words [words.Count - 1]); // last word
    foreach (string s in words) Console.WriteLine (s); // all words
    List<string> subset = words.GetRange (1, 2); // 2nd->3rd words

    string[] wordsArray = words.ToArray(); // Creates a new typed array

    // Copy first two elements to the end of an existing array:
    string[] existing = new string [1000];
    words.CopyTo (0, existing, 998, 2);

    List<string> bigWords = words.ConvertAll <string> // Converts to
    (delegate (string s) { return s.ToUpper(); } ); // uppercase

    List<int> lengths = words.ConvertAll <int>
    (delegate (string s) { return s.Length; } );

    Using LinkedList<T>:

    LinkedList<string> tune = new LinkedList<string>();
    tune.AddFirst ("do"); // do
    tune.AddLast ("so"); // do - so

    tune.AddAfter (tune.First, "re"); // do - re - so
    tune.AddAfter (tune.First.Next, "mi"); // do - re - mi - so
    tune.AddBefore (tune.Last, "fa"); // do - re - mi - fa - so

    tune.RemoveFirst(); // re - mi - fa - so
    tune.RemoveLast(); // re - mi - fa

    LinkedListNode<string> miNode = tune.Find ("mi");
    tune.Remove (miNode); // re - fa
    tune.AddFirst (miNode); // mi - re - fa

    foreach (string s in tune) Console.WriteLine (s);

    Using Queue<T>:

    Queue<int> q = new Queue<int>();
    q.Enqueue (10);
    q.Enqueue (20);
    int[] data = q.ToArray(); // Exports to an array
    Console.WriteLine (q.Count); // "2"
    Console.WriteLine (q.Peek()); // "10"
    Console.WriteLine (q.Dequeue()); // "10"
    Console.WriteLine (q.Dequeue()); // "20"
    Console.WriteLine (q.Dequeue()); // throws an exception (queue empty)

    Using Stack<T>:

    Stack<int> s = new Stack<int>();
    s.Push (1); // Stack = 1
    s.Push (2); // Stack = 1,2
    s.Push (3); // Stack = 1,2,3
    Console.WriteLine (s.Count); // Prints 3
    Console.WriteLine (s.Peek()); // Prints 3, Stack = 1,2,3
    Console.WriteLine (s.Pop()); // Prints 3, Stack = 1,2
    Console.WriteLine (s.Pop()); // Prints 2, Stack = 1
    Console.WriteLine (s.Pop()); // Prints 1, Stack = <empty>
    Console.WriteLine (s.Pop()); // throws exception

    Using HashSet<T>:

    HashSet<char> letters = new HashSet<char> ("the quick brown fox");

    Console.WriteLine (letters.Contains ('t')); // true
    Console.WriteLine (letters.Contains ('j')); // false

    foreach (char c in letters) Console.Write (c); // the quickbrownfx
    HashSet<char> letters = new HashSet<char> ("the quick brown fox");
    letters.IntersectWith ("aeiou");
    foreach (char c in letters) Console.Write (c); // euio
    HashSet<char> letters = new HashSet<char> ("the quick brown fox");
    letters.ExceptWith ("aeiou");
    foreach (char c in letters) Console.Write (c); // th qckbrwnfx
    HashSet<char> letters = new HashSet<char> ("the quick brown fox");
    letters.SymmetricExceptWith ("the lazy brown fox");
    foreach (char c in letters) Console.Write (c); // quicklazy

    Using Dictionary<TKey,TValue>:

    var d = new Dictionary<string, int>();

    d.Add("One", 1);
    d["Two"] = 2; // adds to dictionary because "two" not already present
    d["Two"] = 22; // updates dictionary because "two" is now present
    d["Three"] = 3;

    Console.WriteLine (d["Two"]); // Prints "22"
    Console.WriteLine (d.ContainsKey ("One")); // true (fast operation)
    Console.WriteLine (d.ContainsValue (3)); // true (slow operation)
    int val = 0;
    if (!d.TryGetValue ("onE", out val))
    Console.WriteLine ("No val"); // "No val" (case sensitive)

    // Three different ways to enumerate the dictionary:

    foreach (KeyValuePair<string, int> kv in d) // One ; 1
    Console.WriteLine (kv.Key + "; " + kv.Value); // Two ; 22
    // Three ; 3

    foreach (string s in d.Keys) Console.Write (s); // OneTwoThree
    Console.WriteLine();
    foreach (int i in d.Values) Console.Write (i); // 1223

    Using SortedDictionary<TKey,TValue>:

    // MethodInfo is in the System.Reflection namespace
    //该方法位于System.Reflection命名空间中

    var sorted = new SortedList <string, MethodInfo>();

    foreach (MethodInfo m in typeof (object).GetMethods())
    sorted [m.Name] = m;

    foreach (string name in sorted.Keys)
    Console.WriteLine (name);

    foreach (MethodInfo m in sorted.Values)
    Console.WriteLine (m.Name + " returns a " + m.ReturnType);

    Console.WriteLine (sorted ["GetHashCode"]); // Int32 GetHashCode()

    Console.WriteLine (sorted.Keys [sorted.Count - 1]); // ToString
    Console.WriteLine (sorted.Values[sorted.Count - 1].IsVirtual); // True

    Extending Collection<T>(扩展Collection<T>):

    public class Animal
    {
    public string Name;
    public int Popularity;
    public Zoo Zoo { get; internal set; }

    public Animal(string name, int popularity)
    {
    Name = name; Popularity = popularity;
    }
    }

    public class AnimalCollection : Collection <Animal>
    {
    Zoo zoo;
    public AnimalCollection (Zoo zoo) { this.zoo = zoo; }

    protected override void InsertItem (int index, Animal item)
    {
    base.InsertItem (index, item);
    item.Zoo = zoo;
    }
    protected override void SetItem (int index, Animal item)
    {
    base.SetItem (index, item);
    item.Zoo = zoo;
    }
    protected override void RemoveItem (int index)
    {
    this [index].Zoo = null;
    base.RemoveItem (index);
    }
    protected override void ClearItems()
    {
    foreach (Animal a in this) a.Zoo = null;
    base.ClearItems();
    }
    }

    public class Zoo
    {
    public readonly AnimalCollection Animals;
    public Zoo() { Animals = new AnimalCollection (this); }
    }

    Extending KeyedCollection<,>(扩展KeyedCollection<,>):

    public class Animal
    {
    string name;
    public string Name
    {
    get { return name; }
    set {
    if (Zoo != null) Zoo.NotifyNameChange (this, value);
    name = value;
    }
    }
    public int Popularity;
    public Zoo Zoo { get; internal set; }

    public Animal (string name, int popularity)
    {
    Name = name; Popularity = popularity;
    }
    }

    public class AnimalCollection : KeyedCollection <string, Animal>
    {
    Zoo zoo;
    public AnimalCollection (Zoo zoo) { this.zoo = zoo; }

    internal void NotifyNameChange (Animal a, string newName)
    {
    this.ChangeItemKey (a, newName);
    }

    protected override string GetKeyForItem (Animal item)
    {
    return item.Name;
    }

    // The following methods would be implemented as in the previous example
    protected override void InsertItem (int index, Animal item)...
    protected override void SetItem (int index, Animal item)...
    protected override void RemoveItem (int index)...
    protected override void ClearItems()...
    }

    public class Zoo
    {
    public readonly AnimalCollection Animals;
    public Zoo() { Animals = new AnimalCollection (this); }
    }

    class Program
    {
    static void Main()
    {
    Zoo zoo = new Zoo();
    zoo.Animals.Add (new Animal ("Kangaroo", 10));
    zoo.Animals.Add (new Animal ("Mr Sea Lion", 20));
    Console.WriteLine (zoo.Animals [0].Popularity); // 10
    Console.WriteLine (zoo.Animals ["Mr Sea Lion"].Popularity); // 20
    zoo.Animals ["Kangaroo"].Name = "Mr Roo";
    Console.WriteLine (zoo.Animals ["Mr Roo"].Popularity); // 10
    }
    }

    Using EqualityComparer(比较相等的用例):

    public class Customer
    {
    public string LastName;
    public string FirstName;

    public Customer (string last, string first)
    {
    LastName = last;
    FirstName = first;
    }
    }

    public class LastFirstEqComparer : EqualityComparer <Customer>
    {
    public override bool Equals (Customer x, Customer y)
    {
    return x.LastName == y.LastName && x.FirstName == y.FirstName;
    }

    public override int GetHashCode (Customer obj)
    {
    return (obj.LastName + ";" + obj.FirstName).GetHashCode();
    }
    }

    static void Main()
    {
    Customer c1 = new Customer ("Bloggs", "Joe");
    Customer c2 = new Customer ("Bloggs", "Joe");

    // Because we’ve not overridden object.Equals, normal reference
    // type equality semantics apply:

    Console.WriteLine (c1 == c2); // false
    Console.WriteLine (c1.Equals (c2)); // false

    Dictionary<Customer, string> d = new Dictionary<Customer, string>();
    d [c1] = "Joe";
    Console.WriteLine (d.ContainsKey (c2)); // false

    // Now with the custom equality comparer:

    LastFirstEqComparer eq = new LastFirstEqComparer();
    d = new Dictionary<Customer, string> (eq);
    d [c1] = "Joe";
    Console.WriteLine (d.ContainsKey (c2)); // true
    }

    Using the IComparer interfaces(使用IComparer接口):

    class Wish
    {
    public string Name;
    public int Priority;

    public Wish (string name, int priority)
    {
    Name = name;
    Priority = priority;
    }
    }

    class PriorityComparer : Comparer <Wish>
    {
    public override int Compare (Wish x, Wish y)
    {
    if (object.Equals (x, y)) return 0; // Fail-safe check
    return x.Priority.CompareTo (y.Priority);
    }
    }
    static void Main()
    {
    List<Wish> wishList = new List<Wish>();
    wishList.Add (new Wish ("Peace", 2));
    wishList.Add (new Wish ("Wealth", 3));
    wishList.Add (new Wish ("Love", 2));
    wishList.Add (new Wish ("3 more wishes", 1));

    wishList.Sort (new PriorityComparer());
    foreach (Wish w in wishList) Console.Write (w.Name + " | ");
    }

    SurnameComparer(起始名称的比较):

    class SurnameComparer : Comparer <string>
    {
    StringComparer strCmp;

    public SurnameComparer (CultureInfo ci)
    {
    // Create a case-sensitive, culture-sensitive string comparer
    strCmp = StringComparer.Create (ci, false);
    }

    string Normalize (string s)
    {
    s = s.Trim();
    if (s.ToUpper().StartsWith ("MC")) s = "MAC" + s.Substring (2);
    return s;
    }

    public override int Compare (string x, string y)
    {
    // Directly call Compare on our culture-aware StringComparer
    return strCmp.Compare (Normalize (x), Normalize (y));
    }
    }
  • 相关阅读:
    设计模式-Note9-行为变化类
    设计模式-Note8-数据结构类
    设计模式-Note7-状态变化类
    设计模式-Note6-接口隔离类
    设计模式--Note5--对象性能类
    设计模式--Note4--对象创建类
    设计模式--Note3--单一职责类
    设计模式--Note2--组件协作类
    V$ACCESS 查询结果慢的解决方法
    openstack numa详解(命令使用篇)
  • 原文地址:https://www.cnblogs.com/magic_evan/p/2294737.html
Copyright © 2011-2022 走看看