• ArrayList
    using System.Collections;
    是C#为我们封装好的类,帮助我们实现了许多方法
    本质是一个object类型的数组
    ArrayList array = new ArrayList();
    增:array.Add();
    array.AddRange(array2); //把另一个容器的内容增加到后面

    删:array.Remove(); //移除指定元素,从头找,找到就删掉
    array.RemoveAt(); //移除指定位置的元素
    array.Clear(); //清空

    查:array.Contains(); //判断元素是否存在
    IndexOf(); //正向查找
    LastIndexOf(); //反向查找,返回的索引按正向来

    改:array[0] = "114514";

    插:array.Insert(1,"1919810");

    遍历:
    for(int i = 0; i < array.Count; i++){}
    foreach(var item in array){} //迭代器遍历

    装箱拆箱:
    int x = 1;
    array[0] = x; //装箱
    x = (int)array[0]; //拆箱

  • 栈 Stack
    本质也是object数组,只是封装了特殊的存储规则
    栈是一种先进后出的数据结构,跟取出腌菜缸里的腌菜一样。
    先存入的数据后获取,后存入的先获取
    Stack stack = new Stack()
    增:stack.Push(); //只能一个一个的放入

    取(删,也称弹栈):stack.Pop();

    查(只查看栈顶,不会取出):stack.Peek();
    stack.Contains(); //是否存在

    改:栈无法改变其中的元素,只能放和取
    只能使用stack.Clear(); 清空栈

    遍历:
    无法使用for循环遍历,因为没有提供用[]访问的接口

    可用foreach遍历或转换为object数组后遍历
    foreach(var item in stack){};
    object[] array = stack.ToArray();
    for(int i = 0; i < array.Length; i++){}

    循环弹栈:
    while(stack.Count > 0)
    {
    object o = stack.Pop();
    Console.Write(o);
    }

    可装拆箱

  • 队列 Queue
    本质还是object[]数组,也封装了不明物体
    队列是一种先进先出的数据结构
    先存入的数据先获取,后存入的后获取(先进先出)
    Queue queue = new Queue();
    增:queue.Enqueue();

    删(取):queue.Dequeue(); //取出先加入的对象

    查:queue.Peek(); //看队列头部元素是什么
    queue.Contains(); //查看元素是否存在

    改:也不能改,只能进出队列
    只能使用queue.Clear(); 清空队列

    遍历:
    无法使用for循环遍历,因为没有提供用[]访问的接口
    同栈使用foreach和转换为object[]

    循环出列:
    while(queue.Count>0)
    {
    object o = queue.Dequeue();
    Console.Write(o);
    }

    可装拆箱

  • 哈希表 HashTable
    又称散列表,基于键的哈希代码组织起来的键-值对
    提高数据查询的效率
    使用键来访问集合中的元素
    Hashtable hashtable = new Hashtable();
    增:hashtable.Add( 1 , "14514");

    删:hashtable.Remove(1);
    删除不存在的键不会有反应
    hashtable.Clear();

    查:hashtable[1];
    找不到会返回空
    hashtable.Contains();
    hashtable.ContainsKey(); //两个查找方法没有区别,都是查找是否存在键
    hashtable.ContainsValue(); //查找值

    改:hashtable[1] = 1919;

    遍历:
    无法用for循环遍历
    遍历所有的键:
    foreach(object item in hashtable.Keys)
    {
    Console.Write(hashtable[item]);
    }

    遍历所有的值:
    foreach(object item in hashtable.Values)
    {
    Console.Write(item);
    }

    键值对一起遍历:
    foreach(DictionaryEntry item in hashtable)
    {
    Console.Write(item.Keys + item.Value);
    }

    迭代器遍历:
    IDictionaryEnumerator enumerator = hashtable.GetEnumerator();
    bool flag = enumerator.MoveNext();
    while(flag)
    {
    Console.Write(enumerator.Key + enumerator.Value)
    }

    可装拆箱

  • 泛型
    实现了类型参数化,达到代码重用的目的,相当于类型占位符
    通过类型参数化来实现同一份代码上操作多种类型
    定义类或方法是使用替代符代表变量类型
    当真正使用类或者方法时再具体指定类型

    泛型分类
    泛型占位字母可以有多个,用逗号分开
    泛型类:class 类名<泛型占位字母>
    class TestClass<T>
    {
    public T value;
    }

    TestClass<int> t = new TestClass<int>();
    t.value = 114514;
    Console.Write(t.value)


    泛型接口:interface 接口名<泛型占位字母>
    interface TestInterface<T>
    {
    T Value{get;set;}
    }

    //继承泛型接口
    class Test : TestInterface<int>{}


    泛型函数:函数名<泛型占位字母>(参数列表)
    普通类中的泛型方法:
    class Test
    {
    public void TestFun<T>(T value)
    {
    Console.Write(value);
    }

    //重载用泛型类型在函数内写逻辑
    public void TestFun<T>()
    {
    T t = default(T); //确保变量 t 被安全初始化
    }

    //重载返回值为泛型
    public T TestFun<T>(string v)
    {
    return default(T); //可作为返回值
    }
    }


    泛型类中的泛型方法:
    public Test<T> //类名字一样,但加了泛型就位不同类型
    {
    public T value;

    public void TestFun(T t){} //不为泛型方法,T是泛型类申明时就确定的,使用这个函数的时候就不能动态变化

    public void TestFun<K>(K k) //泛型字母T被类使用,需要更换
    {
    Console.Write(k);
    }
    }


    泛型的作用
    1、不同类型对象的相同逻辑处理就可选择泛型
    2、使用泛型可以一定程度避免装拆箱

  • 泛型约束 where
    where 约束字母:约束条件
    约束条件:
    1、值类型 where T:struct
    2、引用类型 where T:class
    3、存在无参公共构造函数 where T:new()
    4、某个类本身或者其派生类 where T:类名
    5、某个接口的派生类型 where T:接口名
    6、另一个泛型类型本身或者派生类型 where T:另一个泛型字母

    约束可以组合使用,用“,”隔开计科
    多个泛型也可以同时约束,where T:struct where K:class

  • 常用泛型数据结构类
    List、Dictionary、顺序存储和链式存储、Linkedlist、泛型栈和队列

  • List
    本质是一个可变类型的泛型数组
    List<int> list = new List<int>();

    增:list.Add(); listAddRange();
    删:.Remove(); .RemoveAt();
    查:.IndexOf(); .LastIndexOf();
    改:list[0] = 114514; Insert(0,114)

    for和foreach遍历

  • Dictionary
    可以理解为拥有泛型的Hashtable(键值对)
    键值对类型从Hashtable的object变味了可以自己制定的泛型
    Dictionary<int, string> dictionary = new Dictionary<int, string>();

    增:dictionary.Add();
    删:.Remove(); .Clear()
    查:dictionary[1]; ContainsKey(); ContainsValue();
    改:dictionary[1]

    foreach、KeyValuePair、迭代器

  • 顺序存储和链式存储
    顺序存储:
    用一组地址连续的存储单元依次存储线性表的各个数据元素
    数组、Stack、Queu、List、ArrayList

    链式存储:
    用一组任意的存储单元存储到线性表中的各个数据元素
    单向、双向、循环链表

    实现一个单链表:
    class LinkedNode<T>
    {
    public T value;
    public LinkedNode<T> nextNode; //存储的下一个元素是谁

    public LinkedNode(T value)
    {
    this.value = value;
    }
    }

    LinkedNode<int> node = new LinkedNode<int>(1);
    LinkedNode<int> node2 = new LinkedNode<int>(2);
    node.nextNode = node2;

  • LinkedList
    本质是一个可变类型的泛型双向链表
    LinkedList<int> linkedList = new LinkedList<int>();

    增:linkedList.AddFirst(); //头部增加元素
    .AddLast(); //尾部增加元素
    .AddAfter(); //某个节点之后添加
    .AddBefore(); //某个节点之前添加

    删:.RemoveFirst(); RemoveLast(); //移出头结点和尾结点

    查:无法直接通过下标获取中间元素
    linkedList.First; //头结点
    linkedList.Last; //尾结点
    linkedList.Find(); //查找指定位置元素
    .Contains();

    改:先得到结点才能改变其中的值
    linkedList .First.Value = 114514;

    遍历:
    //foreach能直接得到里面的值
    foreach(int item in linkedList)
    {
    Console.WriteLine(item);
    }

    //从头到尾遍历
    LinkedListNode<int> nowNode = linkedList.First; //nowNode用于存储的临时变量
    while(nowNode != null)
    {
    Console.Write(nowNode.Value);
    nowNode = nowHead.Next;
    }

    //从尾到头遍历
    nowNode = linkedList.Last; //nowNode用于存储的临时变量
    while(nowNode != null)
    {
    Console.Write(nowNode.Value);
    nowNode = nowHead.Previous;
    }

  • 泛型栈和队列
    使用上与Stack和Queue一样
    Stack<int> stack = new Stack<int>();
    Queue<object> queue = new Queue<object>();