黑马程序员-自学笔记-集合相关(重难点)

来源:互联网 发布:淘宝中差评外包 编辑:程序博客网 时间:2024/05/17 03:11

集合相关(重难点)

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

1、集合
1)集合可以看做是封装了大量方法的动态数组
2)集合是对象列表,通过实现System.Collections中的接口来获得接口
集合的功能可以通过接口来实现,通过接口可以创建自定义集合类
可以定制强类型的集合类
可以提供专用的方法
3)System.Collections
IEnumerable 可以迭代集合中的项
ICollection 继承自IEnumerable,获得集合中的个数,并将项复制到一个简单数组中
IList 继承自IEnumerable、ICollection,提供集合项列表,及其他功能
IDictionary 继承自IEnumerable、ICollection,提供键值访问的项列表

4)ArrayList也实现了IList、ICollection和IEnumerable

2、定义集合
1)创建自己的集合
1、手写
2、从抽象类CollectionBase中继承

public class <ClassName> : CollectionBase

{

// 添加的方法

public void Add(<typeName> <newName>)

{

List.Add(<newName>);// ArrayList提供的受保护成员,可以直接访问存储的变量本身

}

// 定义删除的方法

public void Remove(<typeName> <oldName>)

{

List.Remove(<oldName>)// IList提供的Add、Remove方法

}

public <ClassName>()

{

// 构造方法

}

// 定义索引器

public <typeName> this[int index]

{

get

{

return (typeName)List[index];// List中为object类型,需要强制转换

}

// set

// {

// List[index] = value;

// }

}


// 定义复制的方法

// 将本类集合中的数据复制到另一个同类型的集合中

public void CopyTo(<ClassName> <name>)

{

for(int i = 0; i < this.Count; i++)// Count为ICollection提供的属性

{

<name>.Add(this[i]);

}

}

// 定义判断是否存在某个元素

public bool Contains(<typeName> <name>)

{

return InnerList.Contains(<name>);// InnerList为CollectionBase提供的受保护方法

}

}


3、关键字值集合和IDictionary
1)集合还可以实现IDictionary接口,实现键值访问的方式
CollectionBase实现IList、ICollection和IEnumerable
DictionaryBase实现IDictionary、ICollection和IEnumerable
2)DictinaryBase中有个受保护的字段Dictionary(IDictionary类型)来实现对数据实体的访问(?)

public class <ClassName> : DictionaryBase

{

pulic void Add(string newId, Person newPerson)

{

Dictionary.Add(newId, newPerson);

}

public void Remove(string personId)

{

Dictionary.Remove(personId);

}

public <ClassName>()

{

}

public Person this[string personId]

{

get

{

return (Person)Dictionary[personId];

}

}

}


4、DictionaryBase与CollectionBase的区别一点事键值关系和索引关系,另一个即为foreach方式
1)CollectionBase的派生类可以直接通过foreach访问得到对应的项
2)DictionaryBase的派生类foreach得到的是DictionaryEntry结构类型,通过Key和Value可以访问对应的键和值

foreach(DictionaryEntry myDictionaryEnty in <DictionaryBaseSubClassName>)

{

myDictionaryEntry.Value...// 得到里面的值

}


5、迭代器
1)IEnumerable接口提供了能foreach的能力
2)foreach迭代collectionObject的过程如下
-> 调用collectionObject的GetEnumerator()方法,得到一个IEnumerator的引用(IEnumerable中定义了该方法)
-> 调用IEnumerator所指对象的MoveNext()方法
-> 如果MoveNext()方法返回true,则使用IEnumerator的Current属性获得对象的一个引用,用于foreach循环
-> 如果返回的是false循环停止
3)如此要重写很多方法,跟踪索引、维护Current属性、执行其他代码等

可以使用迭代器来简单的实现(简化的替代品)

迭代器是一个代码块,提供按顺序提供foreach所要的结果

迭代器可以是一个方法、属性等

迭代器的放回类型是IEnumerable或IEnumerator

若是使用对象迭代得到结果,使用IEnumerator返回类型,并重写GetEnumerator()方法

若是使用成员迭代得到结果,使用IEnumerable返回类型,只需提供对应方法或属性即可

迭代语法为

yield return <需要返回的内容>;

在迭代中遇到

yield break;

则会中断

在迭代的过程中yield会处理索引和Current属性等信息,执行到yield后,会停在该处,返回foreach循环,当执行in时,再次回到上次迭代位置,继续执行

实际上迭代器会被编译器解释为一个嵌套类来实现


4)对于字典集合的迭代,可以使用覆盖基类方法的形式提供GetEnumerator()方法来实现

在类中添加代码

public new IEnumerator GetEnumerator()

{

foreach(object o in <CollectionName>.Values)

{

yield return (<ClassName>)o;

}

}

那么在Main方法中就可以像之前一样使用foreach进行使用了


6、浅度复制与深度复制

Object提供了一个受保护方法MemberwiseClone(),返回当前对象的浅表副本

public class <ClassName>
{
// 其他成员

public object MyClone()
{
return MemberwiseClone();
}
// 其他成员
}

复制的时候使用

<ClassName> <name2> = (<ClassName>)<name1>.MyClone();

但是如果成员中有引用类型,那么复制后引用类型依旧保持同一个对象,因此如果需要使两个对象独立,需要深度复制

可以重写MyClone()方法,也可以使用.Net提供的标准方式:实现ICloneable接口,用Clone方法替代MyClone方法

public class <ClassName>
{
// 其他成员

public object MyClone()
{
<ClassName> temp = new <ClassName>();
// 完成复制操作,实际上就是重新创造一个
// 代码过程
return temp;
}
// 其他成员
}

如果引用类型的某个字段还是引用类型,同样需要使用刚方式实现,好像一个递归一样


7、类型比较
可以使用typeof()运算符比较某个对象是否为某个类型

if(<实例名>.GetType() == typeof(<ClassName>))
{
// 当对象是该类型时执行操作
}

8、装箱(boxing)与拆箱(unboxing)

装箱就是将值类型“赋值”给object或它实现的接口类型,拆箱就是还原

装箱拆箱过程中引用类型依旧保持地址的复制,即装箱后,原来结构中引用类型结果的改变,拆箱后会有影响

9、is运算符

<实例名> is <TypeName>

<TypeName>是一个类、接口,如果实例能被其引用,则返回true

<TypeName>是一个值类型,如果实例能被拆箱,返回true


10、值比较
运算符重载(本质就是函数?)

[访问修饰符] static 返回类型 operator 运算符(参数列表)
{
// 实际运算方式
return 返回结果;
}

注意:不要将签名相同的运算符添加到多个类中,实际运算时,操作数与重载中的参数顺序应一致

允许重载的运算符

一元运算符:+、-、!、~、++、--、true、false

二元运算符:+、-、*、/、%、&、|、^、<<、>>

比较运算符:==、!=、<、>、<=、>=

注意:重载true或false,可以将对象作为bool变量来使用,像if(<实例名分>){ ... }


11、IComparable和IComparer接口

这两个接口是.Net Framework中比较对象的标准方式

IComparable提供一个CompareTo()的方法标准,该方法接收一个对象,可以比较自己和另一个对象

IComparer提供一个Compare()的方法接口,该方法接收两个对象,比较任意两个对象(一般在单独的类中实现)

这两个接口均返回一个int类型


12、Comparer类介绍

在命名空间Syatem.Collections中,类Comparer实现了IComparer接口

可以对简单的类型和实现了IComparable接口的类型进行指定方式的比较(特定文化,比较规则)

可以使用
Comparer.Default.Compare(对象1, 对象2)
来进行比较

注意事项:

1、看比较对象是否支持IComparable,如果支持就使用其实现代码

2、允许为null,表示小于一切

3、字符串使用当前“文化”来处理。需要定义规则,Comparer必须实例化,规则由System.Globalization.CultureInfo对象来指定

4、字符串区分大小写,如果不区分使用CaseInsensitiveComparer类


13、使用IComparable和IComparer接口实现对集合的排序

ArrayList的Sort()方法实现排序

首先看对象是否实现了IComparable接口,如果实现就按照实现的方式进行排序

如果想重新排序,可以写一个类实现IComparer接口,以参数的形式提交给Sort()方法

14、转换

重载的方式提供转换的实现

定义隐式转换使用关键字 implicit
定义显示转换使用关键字 explicit

转换顺序与定义顺序相同: 变量1 = 变量2 对应参数类型1(类型2 value)

语法:
[访问修饰符] static [implicit|explicit] operator 目标类型(待转类型 value)
{
目标类型 o = new 目标类型();
// 赋值操作,显示转换中可以将赋值操作用checked{...}块包起来,如果放不下就异常
return o;
}

15、as运算符

对象 as 类型

对象若是该类型、继承该类型或装箱到该类型中,则返回转换后的类型,否则返回null


---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 打了玻尿酸怀孕怎么办 鼻子上有出血点怎么办 内眼角开小了怎么办 上眼皮肿怎么办小妙招 嫁接的睫毛乱了怎么办 睫毛掉进眼睛里怎么办 痘痘留下的疤痕怎么办 宫颈癌前病变1级怎么办 纹身后结痂很厚怎么办 纹身结痂蹭掉了怎么办 药流20天同房了怎么办 药流23天同房了怎么办 小产后不来月经怎么办 人流12天同房了怎么办 人流20天同房了怎么办 人流后5天同房了怎么办 人流后3天同房了怎么办 人流20后同房了怎么办 上环后月经量多怎么办 上环后喝啤酒了怎么办 取环当天同房了怎么办 生完孩子有外痔怎么办 怀孕了宫腔积液怎么办 做完爱4天怕怀孕怎么办 半永久眉失败了怎么办 取环前2天同房了怎么办 怀孕了发现有子宫肌瘤怎么办 宫腔中央性粘连怎么办 孕妇宫腔粘连带怎么办 内膜厚怎么办吃什么好 功血引起的贫血怎么办 吃宫血宁后月经不来了怎么办 孕晚期胎心不好怎么办 胎心不好怎么办让住院 39 5胎心不好怎么办 肺长了一个肿瘤怎么办 血糖高伤口不愈合怎么办 有轻微的狐臭该怎么办 嘴上汗毛太重怎么办 风把裙子吹起怎么办 每天三四点醒来就睡不着怎么办