— 集合(包括部分字典知识)

动态数组可以添加任意类型数据ArrayList(每一项object,可能需要类型转化)
Convert只有二者在同类型范围才可以转

 

复制代码
static void Main(string[] args)
{
ArrayList list1 = new ArrayList();
list1.Add("aaa");
list1.Add("bbb");
list1.Add("ccc");
list1.Add("asfdadsfa");
list1.Add("asdfasdfsaf");

//list1.Remove("bbb");
list1.RemoveAt(0);

Console.WriteLine(list1[0]);
//Remove一个元素以后后面的元素会递补

PrintList(list1);

Console.WriteLine(list1.Contains("www"));//判断是否存在
Console.WriteLine(list1.Contains("ccc"));

list1.Clear();//清空

Console.WriteLine(list1.Count);

Console.ReadKey();
}

static void Main(string[] args)
{
//<键的类型,值的类型>
Dictionary<string, int> dict = new Dictionary<string, int>();
dict.Add("0108888888888", 30);//放进去一个键值对
dict.Add("1108889998x", 18);
dict.Add("0108888889999", 22);
dict.Add("010888888x", 18);//如果添加相同key的项会报错

//dict.Add("010888888x",19);
//用索引的方式赋值相当于存在就update,不存在就insert
//和Add相比,这种方式不会报错
dict["010888888x"] = 19;
dict["010888888y"] = 19;

int age = dict["0108888888888"];//按照key找value
Console.WriteLine(age);

// dict.Remove("010888888x");//移除指定key的值

//dict.Clear();
//Console.WriteLine(dict.ContainsKey("0108888888888"));
//Console.WriteLine(dict.ContainsKey("afdasfasdfdsa"));
//判断是否存在key

foreach (string key in dict.Keys)
{
int value = dict[key];//select * from ...where id=@Id
Console.WriteLine("{0}={1}", key, value);
}
复制代码

 

用ArrayList的麻烦的地方:数据放进去就不知道是什么类型的了;不能防止非法类型数据的放入;将ArrayList返回给其他函数,会令调用者很困惑。要区分变量、返回值类型和实际对象类型的区别。IntArrayList,StringArrayList又没完没了。
我们需要泛型的ArrayList,所以就有了List<T>。List<int> 除此之外并无不同,<int>表示List中放的数据类型是int类型的,因为有声明类型时的约定,因此所有方法的参数、返回值都是确定类型的了。
从一个整数的ArrayList、List<int>中取出最大数。别用max方法。
List<int> 实现了IEnumerable<int>(泛型版本的IEnumerable)、ICollection<int> (泛型版本的ICollection) 。
所有的List<T>所有的方法也都是泛型的,范型的集合提供的方法更多,Max、Min、Sort等,讲Linq的时候会详细介绍。

ArrayList(非泛,只能object)和List(泛型,任意类型,包括自定义的类)都属于集合System.Collection(包括泛型集合【Dictionary、List、HashSet、IList<T>, ICollection<T>, IEnumerable<T>,】和非泛型集合【ArrayList、Hashtable】)

using System.Collections;非泛型命名空间
// 摘要:
// 定义所有非泛型集合的大小、枚举数和同步方法。
[ComVisible(true)]
public interface ICollection : IEnumerable

using System.Collections.Generic;泛型命名空间


二 集合(Collections)Lamda

IList和List<T>(前者如果不加<T>,只能是非泛型;后者只能是泛型,必须加<T>,List不存在)
IEnumerable和IEnumerable<T>和Enumerable(IEnumerable<T>继承自 IEnumerable,
二者都是为实现简单的循环迭代(类似foreach,只有实现IEnumerable接口foreach才能用)提供的接口,前者为非泛型提供,后者泛型;Enumerable提供一组用于查询实现 System.Collections.Generic.IEnumerable<T> 的对象的 static(在 Visual
// Basic 中为 Shared)方法。)
List<T> : IList<T>(除了前者继承后者;前者类,方法多;后者接口,方法少,只定义常用的几个方法,前者给实现的)
Dictionary<K,V>的非泛型对应的是Hashtable;List<T>→ArrayList
HashSet<T>:不能盛放重复的数据,重复的数据只保留一份。
泛型(返回T)ArrayList : IList::ICollection:IEnumerable:ICloneable

注意List()是个方法
(*)Stack<T>,栈,先入后出,Push(压栈)、Pop(出栈)。
(*)Queue<T>,队列,先入先出:Enqueue(入队)、Dequeue(出队)


// 摘要:
// 提供一组用于查询实现 System.Collections.Generic.IEnumerable<T> 的对象的 static(在 Visual
// Basic 中为 Shared)方法。
public static class Enumerable

_________________________________________
public interface IEnumerable
{
// 摘要:
// 返回一个循环访问集合的枚举数。------类似foreach
//
// 返回结果:
// 可用于循环访问集合的 System.Collections.IEnumerator 对象。

摘要:
// 支持对非泛型集合的简单迭代(类似foreach)
[ComVisible(true)]
[Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
// 摘要:
// 获取集合中的当前元素。
//
// 返回结果:
// 集合中的当前元素。
//
// 异常:
// System.InvalidOperationException:
// 枚举数定位在该集合的第一个元素之前或最后一个元素之后。
object Current { get; }

// 摘要:
// 将枚举数推进到集合的下一个元素。
//
// 返回结果:
// 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
bool MoveNext();
//
// 摘要:
// 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
void Reset();
}
}

三 字典(属于集合)

Key-value Pair 键值对。成语不可以重复,但是解释可以重复。
Dictionary<K,V>:
Add:添加,如果重复,则报错
索引器方式设置值:可以重复设置,即使不存在也没关系,如果重复则新数据覆盖旧数据
ContainsKey,判断是否存在这个Key
(常考)Dictionary<K,V>的非泛型对应的是Hashtable;List<T>→ArrayList

ASP.NET 程序员天天要打交道的 Application、Cache、Session、Request.Params等均由 Dictionary /Hashtable 实现。数据库中的索引也是相似的原理。
自己动手写Dictionary<char, char> 。Dictionary性能测试(做火星文翻译200次)。为什么速度这么快?
查字典为什么能这么快?目录中记录了每个汉字的页码,查找的时候先看汉字的页码,再翻到指定的页就可以非常快速的找到词条了


Dictionary中有一个存储键值对的区域,采用一个固定算法(散列算法,非常快,可以认为时间复杂度为O(1) )根据key来计算这个kvp存放的地址,计算key的值的键值对应该存储的地址,将键值对放入指定的地址即可。查找的时候首先计算key的地址,就可以找到数据了。根据key找房间号,而不是逐个房间找。(*)

HashSet<T>:不能盛放重复的数据,重复的数据只保留一份。Add(T value)添加元素;Contains(T value)判断是否存在元素,HashSet使用了和Dictionary类似的算法,因此Contains方法效率非常高,时间复杂度为O(1)。
面试题:取出整数数组中不重复数据的个数,{30,31,99,38,31,99,50}。
面试题:现有1~10共10个整数,已随机放入一个有8个元素的数组a[8]。要求找出没有被放入数组的那2个数。注意:程序不用实现自然数随机放入数组的过程,测试数据{9,8,5,3,1,10,2,7}。
(*)Stack<T>,栈,先入后出,Push(压栈)、Pop(出栈)。
(*)Queue<T>,队列,先入先出:Enqueue(入队)、Dequeue(出队) ===========转自博客园