集合
本文主要介绍如何使用对象组,讨论数组列表、字典和集合,以及如何在C#代码中正确使用它们,以获得最佳性能。
一、对象组
在.NET基类中,最简单的数据结构是数组,它是System.Array类的一个实例,数组的有点是可以高效的访问给定下标的元素,使用数组编程比较直观;缺点是实例化时必须指定数组的大小,且不能添加、插入或删除元素。另外数组还必须给定下标 才能访问其中的元素,但在对数组元素进行遍历的时候,这个下标并不是很有用。
.NET扩展了对许多在不同环境下使用的其他数据结构的支持,不仅如此,.NET还有许多接口,类实现这些接口后,就可以声明它们支持某种数据结构类型的全部功能。下面介绍3个这样的结构:(下面几种结构类都在System.Collections命名空间中)
1、数组列表
2、集合
3、字典
1.1 数组列表(System.Collections.ArrayList)
ArrayList和StringBuilder相似,其容量可以自动增长。即初始化的时候可以指定其容量(默认值是16),当添加的对象数超出其容量的时候,ArrayList的容量就会自动增大,新增的内存区域可以是成倍增长。
下面是ArrayList的一些基本功能:
ArrayList vectors = new ArrayList(20);
//或者使用默认值
ArrayList vectors = new ArrayList();
//添加元素
vectors.Add(new vector(2,1,2));
//访问元素
vector element1 = (vector)vectors[1];
//插入元素
vectors.Insert(1,new vector(2,4,2));
//删除元素
vectors.RemoveAt(1);
//可以改变ArrayList的容量
vectors.Capacity = 30;
//获取列表中元素的个数
int eleCount = vectors.Count;

//数据列表和数组之间的转换
vector[] vectorsArray = new vector[vectors.Count];
for(int i = 0; i<vectors.Count; i++)
{
  vectorsArray[i] = (vector)vectors[i];
} 
1.2 集合
集合表示一组可以通过遍历每个元素来访问的一组对象,特别是可以使用foreach循环来访问它们。使用foreach循环是集合的主要目的,并无其它特性。
集合要能使用foreach循环,必须实现System.Collections.IEnumerable接口
interface IEnumerable
{
  object Current {get;}
  bool MoveNext();
  void Reset();
}
下面给出一个例子,对Vector结构实现IEnumerable接口。
 struct Vector :  IEnumerable
    {
        public double x, y, z;
        public IEnumerable GetEnumerator()
        {
            return new VectorEnumerator(this);
        }
        private class VectorEnumerator:IEnumerable
        {
            private Vector theVector;
            private int location;

            public VectorEnumerator(Vector theVector)
            {
                this.theVector = theVector;
                this.location = -1;
            }

            public bool MoveNext()
            {
                ++location;
                return (location > 2) ? false : true;
            }

            public object Current
            {
                get
                {
                    if (location < 0 || location > 3)
                    {
                        throw new InvalidOperationException("the enumerator is either before the first element or after the last element of the vector");
                        
                    }
                    return theVector[(uint)location];
                }
            }
            public void Reset()
            
            {
                location = -1;
            }
        
        }
    }
1.3 字典
字典还可以称为映射或散列表,这种数据结构允许按照某个键来访问元素,键可以是任意数据类型,也可以向字典任意添加和删除元素。
在.NET中基本的字典是由HashTable类来表示的,其键和条目都是object类型。其基本用法如下:
HashTable employees = new HashTable(53);//用素数初始化指定HashTable的容量,工作效率高
//添加元素
employees.Add(id,data);//id和data都是对象数据
//获取元素
EmployeeData data = employees[id];
//删除元素
employees.Remove(id);
//获取元素个数
int nEmployee = employees.Count;
下面是一个字典的实例:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;


namespace ZidianTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TestHarness harness = new TestHarness();
            harness.Run();
        }
    }

    class EmployeeID         //键值对象,必须重写Equals()和GetHashCode()
    {
        private readonly char prefix;
        private readonly int number;
        public EmployeeID(string id)
        {
            prefix = (id.ToUpper())[0];
            number = int.Parse(id.Substring(1, 3));
        }
        public override string ToString()
        {
            return prefix.ToString() + string.Format("{0,3:000}",number);
        }
        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }
        public override bool Equals(object obj)
        {
            EmployeeID rhs = obj as EmployeeID;
            if (rhs == null)
            {
                return false;
            }
            if (prefix == rhs.prefix && number == rhs.number)
            {
                return true;
            }

            return false;
        }
    }

    class EmployeeDate  //数据对象
    {
        private string name;
        private decimal salary;
        private EmployeeID id;

        public EmployeeDate(EmployeeID id, string name, decimal salary)
        {
            this.id = id;
            this.salary = salary;
            this.name = name;
        }
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(id.ToString(), 100);
            sb.Append(":");
            sb.Append(string.Format("{0,-20}", name));
            sb.Append(" ");
            sb.Append(string.Format("{0:C}", salary));
            
            return sb.ToString();
        }
    }

    class TestHarness  //测试类
    {

        System.Collections.Hashtable employees = new Hashtable(31);
        public void Run()
        {
            EmployeeID idMortimer = new EmployeeID("B001");
            EmployeeDate mortimer = new EmployeeDate(idMortimer, "Mortimer", 100000.00M);
            EmployeeID idArabel = new EmployeeID("W234");
            EmployeeDate arabel = new EmployeeDate(idArabel, "Arabel Jones", 10000.00M);
            employees.Add(idMortimer, mortimer);
            employees.Add(idArabel, arabel);
            while (true)
            {
                try
                {
                    Console.Write("Enter employee ID(format:A999,X to exit)>");
                    string userInput = Console.ReadLine();
                    userInput = userInput.ToUpper();
                    if (userInput == "X")
                    {
                        return;
                    }
                    EmployeeID id = new EmployeeID(userInput);
                    DisplayData(id);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception occurred. Did you user the correct format for the employee ID?");
                    Console.WriteLine(e.Message);
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
        }
        private void DisplayData(EmployeeID id)
        {
            object empobj = employees[id];
            if (empobj != null)
            {
                EmployeeDate employee = (EmployeeDate)empobj;
                Console.WriteLine("Employee:" + employee.ToString());
            }
            else
            {
                Console.WriteLine("Employee not found:ID=" + id);
            }
        }
    }    

}
一、对象组
在.NET基类中,最简单的数据结构是数组,它是System.Array类的一个实例,数组的有点是可以高效的访问给定下标的元素,使用数组编程比较直观;缺点是实例化时必须指定数组的大小,且不能添加、插入或删除元素。另外数组还必须给定下标 才能访问其中的元素,但在对数组元素进行遍历的时候,这个下标并不是很有用。
.NET扩展了对许多在不同环境下使用的其他数据结构的支持,不仅如此,.NET还有许多接口,类实现这些接口后,就可以声明它们支持某种数据结构类型的全部功能。下面介绍3个这样的结构:(下面几种结构类都在System.Collections命名空间中)
1、数组列表
2、集合
3、字典
1.1 数组列表(System.Collections.ArrayList)
ArrayList和StringBuilder相似,其容量可以自动增长。即初始化的时候可以指定其容量(默认值是16),当添加的对象数超出其容量的时候,ArrayList的容量就会自动增大,新增的内存区域可以是成倍增长。
下面是ArrayList的一些基本功能:
ArrayList vectors = new ArrayList(20);
//或者使用默认值
ArrayList vectors = new ArrayList();
//添加元素
vectors.Add(new vector(2,1,2));
//访问元素
vector element1 = (vector)vectors[1];
//插入元素
vectors.Insert(1,new vector(2,4,2));
//删除元素
vectors.RemoveAt(1);
//可以改变ArrayList的容量
vectors.Capacity = 30;
//获取列表中元素的个数
int eleCount = vectors.Count;
//数据列表和数组之间的转换
vector[] vectorsArray = new vector[vectors.Count];
for(int i = 0; i<vectors.Count; i++)
{
  vectorsArray[i] = (vector)vectors[i];
} 1.2 集合
集合表示一组可以通过遍历每个元素来访问的一组对象,特别是可以使用foreach循环来访问它们。使用foreach循环是集合的主要目的,并无其它特性。
集合要能使用foreach循环,必须实现System.Collections.IEnumerable接口
interface IEnumerable
{
  object Current {get;}
  bool MoveNext();
  void Reset();
}
 struct Vector :  IEnumerable
    {
        public double x, y, z;
        public IEnumerable GetEnumerator()
        {
            return new VectorEnumerator(this);
        }
        private class VectorEnumerator:IEnumerable
        {
            private Vector theVector;
            private int location;
            public VectorEnumerator(Vector theVector)
            {
                this.theVector = theVector;
                this.location = -1;
            }
            public bool MoveNext()
            {
                ++location;
                return (location > 2) ? false : true;
            }
            public object Current
            {
                get
                {
                    if (location < 0 || location > 3)
                    {
                        throw new InvalidOperationException("the enumerator is either before the first element or after the last element of the vector");
                        
                    }
                    return theVector[(uint)location];
                }
            }
            public void Reset()
            
            {
                location = -1;
            }
        
        }
    }1.3 字典
字典还可以称为映射或散列表,这种数据结构允许按照某个键来访问元素,键可以是任意数据类型,也可以向字典任意添加和删除元素。
在.NET中基本的字典是由HashTable类来表示的,其键和条目都是object类型。其基本用法如下:
HashTable employees = new HashTable(53);//用素数初始化指定HashTable的容量,工作效率高
//添加元素
employees.Add(id,data);//id和data都是对象数据
//获取元素
EmployeeData data = employees[id];
//删除元素
employees.Remove(id);
//获取元素个数
int nEmployee = employees.Count;
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ZidianTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TestHarness harness = new TestHarness();
            harness.Run();
        }
    }
    class EmployeeID         //键值对象,必须重写Equals()和GetHashCode()
    {
        private readonly char prefix;
        private readonly int number;
        public EmployeeID(string id)
        {
            prefix = (id.ToUpper())[0];
            number = int.Parse(id.Substring(1, 3));
        }
        public override string ToString()
        {
            return prefix.ToString() + string.Format("{0,3:000}",number);
        }
        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }
        public override bool Equals(object obj)
        {
            EmployeeID rhs = obj as EmployeeID;
            if (rhs == null)
            {
                return false;
            }
            if (prefix == rhs.prefix && number == rhs.number)
            {
                return true;
            }
            return false;
        }
    }
    class EmployeeDate  //数据对象
    {
        private string name;
        private decimal salary;
        private EmployeeID id;
        public EmployeeDate(EmployeeID id, string name, decimal salary)
        {
            this.id = id;
            this.salary = salary;
            this.name = name;
        }
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(id.ToString(), 100);
            sb.Append(":");
            sb.Append(string.Format("{0,-20}", name));
            sb.Append(" ");
            sb.Append(string.Format("{0:C}", salary));
            
            return sb.ToString();
        }
    }
    class TestHarness  //测试类
    {
        System.Collections.Hashtable employees = new Hashtable(31);
        public void Run()
        {
            EmployeeID idMortimer = new EmployeeID("B001");
            EmployeeDate mortimer = new EmployeeDate(idMortimer, "Mortimer", 100000.00M);
            EmployeeID idArabel = new EmployeeID("W234");
            EmployeeDate arabel = new EmployeeDate(idArabel, "Arabel Jones", 10000.00M);
            employees.Add(idMortimer, mortimer);
            employees.Add(idArabel, arabel);
            while (true)
            {
                try
                {
                    Console.Write("Enter employee ID(format:A999,X to exit)>");
                    string userInput = Console.ReadLine();
                    userInput = userInput.ToUpper();
                    if (userInput == "X")
                    {
                        return;
                    }
                    EmployeeID id = new EmployeeID(userInput);
                    DisplayData(id);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception occurred. Did you user the correct format for the employee ID?");
                    Console.WriteLine(e.Message);
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
        }
        private void DisplayData(EmployeeID id)
        {
            object empobj = employees[id];
            if (empobj != null)
            {
                EmployeeDate employee = (EmployeeDate)empobj;
                Console.WriteLine("Employee:" + employee.ToString());
            }
            else
            {
                Console.WriteLine("Employee not found:ID=" + id);
            }
        }
    }    
}
                    
                

  
                
            
        
浙公网安备 33010602011771号