集合

本文主要介绍如何使用对象组,讨论数组列表、字典和集合,以及如何在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(13));
        }

        
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);
            }

        }

    }
    

}

posted @ 2007-02-08 15:52  C#开源即时通讯GGTalk  阅读(1044)  评论(1编辑  收藏  举报