C#编程(四十九)----------队列
队列
1.Queue定义
System.Collections.Queue类表示对象的先进先出集合,存储在Queue(队列)中的对象在一端插入,从另一端移除.
2.优点
(1).能对集合进行顺序处理(先进先出)
(2)能接受null值,并且允许重复的元素
3.Queue的构造器
构造器函数 |
注释 |
Queue() |
初始化Queue类的新实例,该实例为空,具有默认初始容量(32)并使用默认增长因子(2.0) |
Queue(ICollection) |
初始化Queue类的新实例,该实例包含从指定集合复制的元素,具有与所复制的元素数相同的初始容量并使用默认增长因子 |
Queue(Int32) |
初始化Queue类的新实例,该实例为空,具有指定的初始容量并使用默认增长因子 |
Queue(Int32,single) |
初始化Queue类的新实例,该实例为空,具有指定的初始容量并使用指定的增长因子 |
4.Queue属性
属性名 |
注释 |
Count |
获取Queue中包含的元素数 |
5.Queue的方法
方法名 |
注释 |
void Clear() |
从Queue中移除所有对象 |
bool Contains(object obj) |
确定某元素是否在Queue中 |
object Clone() |
创建Queue的浅表副本 |
void CopyTo(Array array,int index) |
从指定数组索引开始讲Queue元素复制到现有的以为Array中 |
object Dequeue() |
移除并返回位于Queue开始处的对象 |
void Enqueue() |
将对象添加到Queue的结尾处 |
object Peek() |
返回位于Queue开始处的对象但不将其移除 |
object[]ToArray() |
将Queue元素复制到新的数组 |
void TrimToSize() |
将容量设置为Queue中元素的实际数目 |
6.Queue的使用案例
好
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 队列
{
class Program
{
static void Main(string[] args)
{
//创建一个队列
Queue myQ = new Queue();
myQ.Enqueue("The");//入队
myQ.Enqueue("quick");
myQ.Enqueue("brown");
myQ.Enqueue("fox");
myQ.Enqueue(null);//添加null
myQ.Enqueue("fox");//添加重复元素;
//打印队列的数量和值
Console.WriteLine("myQ");
Console.WriteLine("\tCount: {0}",myQ.Count);
//打印队列中的所有值
Console.WriteLine("Queue Values");
PrintValues(myQ);
//打印队列中的第一个元素,并移除
Console.WriteLine("(Dequeue\t{0})", myQ.Dequeue());
//打印队列中的所有值
Console.WriteLine("Queue Values");
PrintValues(myQ);
//打印队列中的第一个元素
Console.WriteLine("(Peek) \t{0}",myQ.Peek());
//打印队列中的所有值
Console.WriteLine("Queue Values");
PrintValues(myQ);
Console.ReadKey();
}
public static void PrintValues(IEnumerable myCollection)
{
foreach (object item in myCollection)
{
Console.WriteLine(" {0}",item);
}
Console.WriteLine();
}
}
}
7.备注
(1)Queue的容量是Queue可以保存的元素数.Queue的默认初始容量是32.箱Queue添加元素时,将通过重新分配来根据需要自动增大容量.可通过调用TrimToSize来减少容量.等比因子是当需要更大容量时当前容量要乘以的数字.在狗仔Queue时确定增长因子.默认增长因子为2.0.
(2)Queue能接受空引用作为有效值,并且允许重复的元素.
(3)空引用可以作为值添加到Queue.若要区分空值和Queue结尾,请检查Count属性或捕捉Queue为空时引发的InvalidOperationException异常.
案例:配合线程
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
/*
* 元素以先进先出的方式来处理的集合,第一个来,第一个走
* 例如:飞机登记排队,靠前的就先上飞机,不过队列有优先级
* 如同经济舱和商务舱的队,是两个不同的队,而商务舱优先
* 在.NEt技术中,using System.Collections.Generic.Queue<T>
* 是队列的泛型版本实现
* System.Collections.Queue是非泛型的实现,参数是object
* public class Queue<T>:IEnumerable<T>,ICollection,IEnumerable
* 从队列的定义可以看出,它实现了迭代,集合接口,他没有实现ICollection<T>这个接口,因为
* 其中定义的Add Remove方法会破坏队列
* 队列与列表的主要区别就是,队列没有实现IList接口
* 所以,不可以用索引器访问队列,队列只允许添加元素,
* 该元素只能放在队列的最后(Enqueue()),还有就是从头部去元素Dequeue()
* Enqueue从队列的后面插入元素,而Dequeue在取一个元素的同时,
* 会先将取出的元素删除,如再调用一次,就删除下一个元素
*
*
* 案例:使用一个线程将文档添加到队列中,
* 用另一个线程读取队列
* 存储队列的类型是Document,我们先定义了一个文档类
* 接着定义一个文档处理类DocumentManager,
* 其中包含了添加与读取方法,还有一个属性确定队列是不是为空
* 然后我们定义一个ProcessDocuments来处理线程,操作文档
*/
namespace 队列和线程
{
class Program
{
static void Main(string[] args)
{
DocumentManager mg = new DocumentManager();
ProcessDocuments process = new ProcessDocuments(mg);
//启动读取线程,不过现在没有内容,要等一会加入后,就能读到了
ProcessDocuments.Start(mg);
Document doc = null;
for (int i = 0; i < 500; i++)
{
doc = new Document("syx : " + i, "hello,I love You");
mg.AddDocument(doc);
//睡会,让给其他线程玩
Thread.Sleep(20);
}
Console.ReadKey();
}
}
/// <summary>
/// 文档类,描述类文档的标题与内容
/// </summary>
public class Document
{
public string title;
public string content;
public Document(string title, string content)
{
this.title = title;
this.content = content;
}
}
public class DocumentManager
{
//定义队列集合
private readonly Queue<Document> docQueue = new Queue<Document>();
//添加文档
public void AddDocument(Document doc)
{
//从队列一端插入内容
docQueue.Enqueue(doc);
Console.WriteLine("成功插入文档: {0} ",doc.title);
}
//读取文档
public Document GetDocument()
{
Document doc = null;
lock (this)
{
doc = docQueue.Dequeue();
return doc;
}
}
//只读属性,确定队列中是不是还有元素
public bool IsDocumentAvailable
{
get { return docQueue.Count > 0; }
}
}
//处理文档类
public class ProcessDocuments
{
private DocumentManager dm;
public ProcessDocuments(DocumentManager dm)
{
this.dm = dm;
}
public static void Start(DocumentManager manager)
{
//参数:public delegate void ThreadStart();
new Thread(new ProcessDocuments(manager).DoThreadFunc).Start();
}
public void DoThreadFunc()
{
while (true)
{
if (this.dm.IsDocumentAvailable)
{
Document doc = this.dm.GetDocument();
Console.WriteLine("从队列中读到读取并删除文档 标题:{0} 内容: {1}", doc.title, doc.content);
}
}
}
}
}