C#高级编程(第9版) 第10章 集合 笔记

话说 虽然敲过好多代码, 但除了C++,一直没正眼瞧过其它语言。

今天 看公司老项目的src,c#的,linq+Dictionary的用法有感。所以找来C#的资料 就学了一下,妈的 变天儿了。

以后不能再用C++编写思路,囫囵着过日子了。

------------------------------------------------------------------ 我是分割线 -----------------------------------------------------------------------

以下 学习笔记

列表List<T>、队列、栈、链表、字典和集;

位数组 和 并发集合 【多线程环境使用】

集合借口和类型

大多数集合类在System.Collections 和 System.Collections.Generic命名空间中。

泛型集合 ==> System.Collections.Generic

专用于特定类型的集合类 ==> System.Collections.Concurrent

不可变的集合类 ==> System.Collections.Immutable

列表

.NET Framework为动态列表提供了泛型类 List<T>。

这个类实现了IList、ICollection、IEnumerable、IList<T>、ICollection<T>和IEnumerable<T>接口。

ArrayList是一个非泛型列表,它可以将任意Object类型作为其元素。

使用默认的构造函数创建一个空列表。元素添加到列表中后,列表的容量就会扩大为可容纳4个元素。如果添加了第5个元素,列表的大小就成新设置为包含8个元素,如果8个元素还不够,列表的大小就重新设置为包含16个元素。每次都会将列表的容量重新设置为原来的2倍。

如果列表的内容改变了,整个集合就要重新分配到一个新的内存块中。即创建一个新的数组,大小是原来的2倍。

创建指定元素个数的列表

List<int> intList = new List<int>(10);

可以通过索引访问的集合类有 ArrayList、StringCollection 和 List<T>

ForEach()方法遍历集合中的每一项,调用作为每一项的参数传递的方法。

public delegate void Action<T> (T obj);
public void ActionHandler (Racer obj);
racers.ForEach( Console.WriteLine );
racers.ForEach( r => Console.WriteLine("{0:A}", r); //lambda表达式

删除元素

删除元素时,可以利用索引,也可以传递要删除的元素。

按索引删除比较快,因为必须在集合中搜索要删除的元素。Remove()方法现在集合中搜索,用IndexOf()方法获取元素的索引,在使用该索引删除元素。IndexOf()方法先检查元素类型是否实现了IEquatable<T>接口。如果是就调用这个接口的Equals()方法,确定集合中的元素是否等于传递给Equals()方法的元素。如果没有实现这个接口,就使用Object类的Equals()方法比较这些元素。Object类中的Equals()方法的默认实现代码对值类型进行比较,对引用类型只比较其引用。

重写IEquatable<T>接口或Object.Equals()方法可以根据列表元素对象的特定属性进行删除列表元素。

第7章 介绍如何重写Equals()方法

搜索

有不同的方式在集合中搜索元素。可以获得要查找的元素的引用,或者搜索元素本身。

方法有:

IndexOf()
LastIndexOf()
FindIndex()
FindLastIndex()
Find()
FindLast()
检查元素是否存在:List<T>.Exists()方法;

IndexOf()可以指定不需要搜索整个集合,需要指定开始索引以及需要迭代的元素个数

FindIndex()可以搜索有某个特性的元素

public int FindIndex(Predicate<T> match); //Predicate<T>类型是一个委托,该委托返回一个bool值

int index = racers.FindIndex( r => r.Country == "FinLand");

FindIndex()方法返回所查找元素的索引。Find()方法除了获得索引之外,还可以直接获得集合中的元素。

Racer racer = racers.Find( r => r.FirstName == "Niki");

要获得于Predicate<T>类型匹配的所有项,而不是一项,可以使用FindAll()方法;

排序

List<T>类可以使用Sort()方法对元素排序。Sort()方法使用快速排序算法。

Sort()方法使用了几个重载的方法:

public void List<T>.Sort();
public void List<T>.Sort(Comparison<T>);
public void List<T>.Sort(IComparer<T>);
public void List<T>.Sort(Int32, Int32, IComparet<T>);

1. 只有集合中的元素实现了IComparable接口,才能使用不带参数的Sort()方法;

2. 如果需要按照元素类型不默认支持的方式排序,就应使用其他技术,如传递一个实现了IComparer<T>接口的对象。

3. 排序的另一种方式使用重载的Sort()方法。

调用Reverse()方法,逆转整个集合的顺序。

类型转换

使用List<T>类的ConvertAll<TOutput>()方法,可以把所有类型的集合转换为另一种类型。

ConvertAll<TOutput>()方法使用一个Converter委托:

public sealed delegate TOutput Converter<TInput, TOutput> (TInput from);

eg:
List<Person> persons = racers.ConvertAll<Person>( r => new Person(r.FirstName + " " + r.LastName));

只读集合

List<T>集合的AsReadOnly()方法返回 ReadOnlyCollection<T>类型的对象。

ReadOnlyCollection<T>类实现的接口与List<T>集合相同,但如若修改将抛出异常NotSupportedException异常。

ReadOnlyCollection<T>还实现了IReadOnlyCollection<T>和IReadOnlyList<T>接口。

队列

Queue<T> 命名空间 System.Collections.Generic

队列是其元素以先进先出(FIFO)的方式来处理的集合。

可以使用多个队列,一个队列对应一个优先级。打印队列和线程队列是这样的。

可以为一组队列建立一个数组,数组中的一项代表一个优先级。

在内部Queue<T>类使用T类型的数组;它实现ICollection和IEnumerable<T>接口。

因为没有实现IList<T>接口,所以不能用索引器访问元素。

Queue<T>方法如下:

Count
Enqueue
Dequeue
Peek //从队列头部读取一个元素但不删除它
TrimExcess //重新设置队列的容量,Dequeue()方法从队列中删除元素,但不会重新设置队列容量,要从队列的头部去除空元素,应使用TrimExcess()方法

多线程可以同时访问,但要是用lock语句锁定队列的访问:

public class DocumentManager {
	private readonly Queue<Document> documentQueue = new Queue<Document>();
 	public void AddDocument(Document doc) {
		lock (this) {
			documentQueue.Enqueue(doc);
		}
	}

	public Document GetDocument() {
		Document doc = null;
		lock (this) {
			doc = documentQueue.Dequeue();
		}
		return doc;
	}

	public bool IsDocumentAvailable {
		get { return documentQueue.Count > 0; }
	}
}

栈是一个后进先出(LIFO)的容器

与Queue<T>类相同,Stack<t>类实现了IEnumerable<T>和ICollection接口。

成员列表:

Count
Push
Pop
Peek
Contains

在foreach方法中,使用IEnumerable接口迭代所有的元素;栈的枚举器不会删除元素,它只是逐个返回元素

链表

LinkedList<T>是一个双向链表

链表的有点事,如果将元素插入列表的中间位置,使用链表就会非常快。

在插入一个元素时,只需要修改上一个元素的Next引用和下一个元素的Previous引用,使它们引用所插入的元素。

在List<T>类中,插入一个元素时,需要移动该元素后面的所有元素。

链表的缺点:链表的元素只能一个接一个地访问,这需要较长的时间来查找位于链表中间或尾部的元素。

有序列表

如果需要基于键对所需集合排序,就可以使用SortList<TKey, TValue>类。这个类按照键给元素排序。

字典

.NET Framework提供了几个字典类,可以使用的最主要的类是Dictionary<TKey, TValue>

键的类型

用作字典中键的类型必须重写Object类的GetHashCode()方法;字典的性能取决于GetHashCode()方法的实现代码。

除了实现GetHashCode()方法之外,键类型还必须实现IEquatable<T>.Equals()方法,或者重写Object类的Equals()方法。

Lookup 类

Lookup<TKey, TElement>把键映射到一个值集上;Lookup<TKey, TElement>类在程序集System.Core中实现,用System.Linq命名空间。

Lookup<TKey, TElement>类不能像一般的字典那样创建,而必须调用ToLookup()方法,该方法返回一个Lookup<TKey, TElement>对象。ToLookup()方法是一个扩展方法,它可以用于实现了IEnumerable<T>接口的所有类。

有序字典

SortedDictionary<TKey, TValue>类是一个二叉搜索树,其中的元素根据键来排序。该键类型必须实现IComparable<TKey>接口。

如果键的类型不能排序,则还可以创建一个实现了IComparer<TKey>接口的比较器,将比较器用作有序字典的构造函数的一个参数。

。。。。 未完待续

时间: 2024-10-28 23:30:21

C#高级编程(第9版) 第10章 集合 笔记的相关文章

【转】apue《UNIX环境高级编程第三版》第一章答案详解

原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此,我要感谢网易的一个工程师朋友和室友,没有他们,我不会开始真正的学习这本书,希望大家以后开始慢慢进步.废话少说,直接上课后习题了. UNIX高级编程第一章习题答案: 1.1在系统上验证,除根目录外,目录l和l l是不同的. 答:这个验证有很多方法可使用命令ls .cd.vim等,目录.指向当前目录,目录..指

C#高级编程第11版 - 第七章

导航 C# 全版本特性一览 全书目录 第七章 Arrays 7.1 相同类型的多个对象 151 7.2 简单数组 152 7.2.1 数组的声明 152 7.2.2 数组的初始化 152 7.2.3 访问数组元素 153 7.2.4 使用引用类型 153 7.3 多维数组 154 7.4 锯齿数组 155 7.5 Array 类 156 7.5.1 创建数组 156 7.5.2 复制数组 156 7.5.3 排序 157 7.6 数组作为参数 159 7.7 数组协变 159 7.8 枚举 16

C#高级编程第11版 - 第二十一章

导航 C# 全版本特性一览 全书目录 第二十一章 Tasks and Parallel Programming 21.1 概述 459 21.2 Parallel 类 460 21.2.1 使用Parallel.For()方法循环 460 21.2.2 提前中断Parallel.For 462 21.2.3 Parallel.For()方法的初始化 462 21.2.4 使用Parallel.ForEach()方法循环 463 21.2.5 通过Parallel.Invoke()方法调用多个方法

C#高级编程第11版 - 第十七章

导航 C# 全版本特性一览 全书目录 第十七章 Managed and Unmanaged Memory 17.1 内存 348 17.2 后台内存管理 349 17.2.1 值数据类型 349 17.2.2 引用数据类型 350 17.2.3 垃圾收集 352 17.3 强引用和弱引用 354 17.4 处理非托管的资源 354 17.4.1 析构函数或终结器 355 17.4.2 IDisposable 接口 356 17.4.3 using 语句 356 17.4.4 实现IDisposa

Linux - Unix环境高级编程(第三版) 代码编译

Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebook.com/code3e.html 2. 安装依赖库:sudo apt-get install libbsd-dev  3. 进入下载目录make 4. 复制头文件和动态链接库 sudo cp ./include/apue.h /usr/include/ sudo cp ./lib/libapue

《UNIX环境高级编程(第3版)》

<UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison-Wesley Professional Computing Series) 原出版社: Addison-Wesley Professional 作者: (美)W. Richard Stevens    Stephen A. Rago 译者: 戚正伟 张亚英 尤晋元 出版社:人民邮电出版社 ISBN:9787

中文版C#高级编程第8版中的翻译错误

第180页,倒数第三行. 英文原文: If you overload == and !=, you must also override the Equals() and GetHashCode() methods inherited from System.Object; 中文译文: 在重载"=="和"!="时,还必须重载(应该是:重写)从System.Object中继承的Equals()和GetHashCode()方法. 中文版C#高级编程第8版中的翻译错误,布

unix环境高级编程(第三版)中apue.h文件的配置问题

最近刚开始学习unix环境高级编程(第三版),其中有个作者自己写的apue.h文件,在这归总下相应的配置方法,希望对有需要的朋友们有所帮助 首先http://www.apuebook.com/code3e.html 上去下载相应的压缩包,注意自己书的版本. 下载完成之后,鉴于大多数朋友学习linux都是基于虚拟机的,所以顺便附上虚拟机与本地主机传输文件的方式 首先下载SSH Secure Shell 这个工具,然后直接点击quick connect, 弹出如下界面,输入虚拟机的ip地址,和登录用

C#高级编程(第8版)——委托声明、使用(第一节)

首先,声明一个Currency的结构.Currency结构有自己的ToString()重载方法和一个与GetCurrencyUnit()的签名相同的静态方法.这样,就可以用同一个委托变量调用这些方法了: struct Currency { public uint Dollars; public ushort Cents; public Currency(uint dollars, ushort cents) { this.Dollars = dollars; this.Cents = cents