structure
数组
这三个类型都是数组,只要是数组,那么它都是内存连续分配、可以用索引值访问、读取快、增删慢。
1、Array
//数组其实就是Array类。
int[] intArray = new int[3];
- Array 的性质:
- 在内存上是连续分配的
- 而且元素类型是一样的
- 所以可以坐标访问
- 特点读取快,增删慢
- 长度不变。
2、ArrayList
- ArrayList性质:
- 元素类型无限制,任何元素都是object
- 长度不变
- 基于Array
3、List
- List性质:
- List也是基于Array的,内存上都是连续摆放的。
- 不定长
- List是泛型的,保证类型安全,避免装箱拆箱。
链表
- 普通链表
- 循环链表:首尾相连,尾指针指向首部。
特点:从链表的任意节点出发都能找到所有节点。
缺点:只能沿单个方向移动。 - 双向链表
- 双向循环链表
1、LinkedList
- LinkedList的性质:
- 它是泛型的。
- 元素不连续分配
- 每个元素都会记录父节点、子节点的地址
- 查找慢,增删快
- 它是链表
LinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddFirst(123);//增加头节点
linkedList.AddLast(11);//增加尾节点
bool isContain = linkedList.Contains(123);//是否包含“123” 元素
LinkedListNode<int> node123 = linkedList.Find(123);//查找元素,返回该节点
linkedList.AddBefore(node123, 1000);//在该节点前增加节点1000
linkedList.AddAfter(node123, 9981);//在该节点后增加节点9981
linkedList.Remove(123);//删除节点
linkedList.Remove(node123);//删除节点
linkedList.RemoveFirst();//删除首节点
linkedList.RemoveLast();//删除尾节点
linkedList.Clear();//清除
2、Queue
- Queue的性质:
- 它是链表,队列,先进先出。
3、Stack
顺序栈:即顺序存储结构的栈,顺序存储结构就是线性表。缺点是定长。
链栈:即链式存储结构的栈。
- Stack的性质:
- 他也是链表,栈,先进后出
Set
- 特性:
- 集合
- hash分布,根据数据内容进行hash算出存放位置,因为相同的值hash算出的位置值也是相同的,所以相同的值会被覆盖(去重原因)。
- 元素间没有关系
- 动态增加容量
- 集合是去重的
- 应用场景:
a. 统计用户IP
普通表操作是,一个统计表,先查找此IP是否重复,不重复则新增一条数据。
哈希表的操作是,只管新增,因为哈希表是去重的。
b. IP投票
1、HashSet
两个哈希集合可以快速的取两个集合的交、差、并、补集。要比使用数组要快。
{
HashSet<string> hashSet = new HashSet<string>();
hashSet.Add("123");
hashSet.Add("1243");
hashSet.Add("1243");
hashSet.Add("1213");
hashSet.Add("1213");
hashSet.Add("1263");
HashSet<string> hashSet2 = new HashSet<string>();
hashSet2.Add("123");
hashSet2.Add("12431");
hashSet2.Add("1243");
hashSet2.Add("12132");
hashSet2.Add("1213");
hashSet2.Add("12633");
hashSet.SymmetricExceptWith(hashSet);//补集
hashSet.UnionWith(hashSet);//并集
hashSet.ExceptWith(hashSet);//差集
hashSet.IntersectWith(hashSet);//交集
}
- 使用场景:二次好友,间接关注,粉丝合集
2、SortedSet
SortedSet也是哈希集合,不同是这个集合会根据内容自动排序。
扩展:IComparer是比较器,可以把排序规则写到这里面。
Key - Value型
1、Hashtable
- Hashtable 是以key-value的形式保存数据的。
- 容量是动态增加的。
- 原理是用key hash计算一个地址,然后放入key-value。如果不同的key hash计算得到了相同的地址值,那么就在得到的地址值上+1,然后在放入key - value(实际上这里就成了一个数组了)。
- 基于这种情况,查找时,如果地址对应的数据的key不对,那就+1查找。
- Hashtable浪费了空间
- 一次定位,增删查改都很快
- 如果数据太多,重复定位,效率就会下降。
- Hashtable是线程安全的。
- 无序的
10.Hashtable的key - value是object的,所以存在装箱和拆箱
//线程安全的
Hashtable.Synchronized(table);
2、Dictionary字典
1、算法原理与Hashtable不完全相同,相似。也是根据key 计算出的地址
2、增删查改都很快
3、有序的
4、线程安全的字典是ConcurrentDictionary
3、SortedDictionary排序字典
1、字面意思,和字典相同。会自动排序。
2、也因为排序,所以增删查改都会慢一些。
4、SortedList 排序集合
1、重复的key会报错
线程安全集合
ConcurrentQueue线程安全版本的Queue
ConcurrentStack线程安全版本的Stack
ConcurrentBag线程安全的对象集合
ConcurrentDictionary线程安全的Dictionary
BlockingCollection
延时查询
1、IEnumerable
IEnumerable<string> query;
- IEnumerable是延时查询的集合,只有在使用时才会去查询。原理是使用迭代器 、yield
- 许多数据结构都实现了IEnumerable接口
- 扩展:迭代器是IEnumerato IEnumerable 和yield的组合
- 迭代器的两种应用:第一种
代码:
public static IEnumerable<string> Test(List<string> cc,参数或操作)
{
foreach (var item in cc)
{
if(参数或操作)
{
yield return item;
}
}
}
- 迭代器的两种应用:第二种
代码;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace 迭代器
{
public static class IEnumeratable
{
public static IEnumerable<TSource> EnumeratorWhen<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> func)
{
if(null == source)
{
throw new Exception("Source");
}
if(null == func)
{
throw new Exception("Func");
}
return new Enumeratorer<TSource>(source, func);
}
}
public class Enumeratorer<TSource> : IEnumerable<TSource>
{
private IEnumerable<TSource> sources;
private Func<TSource, bool> func;
public Enumeratorer(IEnumerable<TSource> sources,Func<TSource,bool>fucn )
{
this.sources = sources;
this.func = fucn;
}
public IEnumerator<TSource> GetEnumerator()
{
foreach(var item in sources)
{
if(func(item))
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
foreach (var item in sources)
{
if (func(item))
{
yield return item;
}
}
}
}
/// <summary>
/// 用到的类
/// </summary>
public class People
{
public int Age { get; set; }
public string Name { get; set; }
}
}
调用:
var list = peoples.EnumeratorWhen(e =>
{
Console.WriteLine("-------------------------------------------------------");
return e.Age < 14;
});
foreach(var item in list)
{
Console.WriteLine("*******************************************************");
Console.WriteLine($"{item.Age}----{item.Name}");
}
2、IQueryable
IQueryable<string> queryable;
使用表达式目录树的延时查询。