using IteratorPattern;
using System;
namespace MyStructure
{
class Program
{
static void Main(string[] args)
{
//1 Array/ArrayList/List/LinkList/Queue/Stack/HashSet/SortedSet
// HashTable/SortedList/Dictionary/SortedDictionary
//2 IEnumerable/ICollection/IList/IQueryble
//3 迭代器模式、yield
//4 dynamic关键字
//a) 集合:纯粹的数据集合,会去重,无序(当然SortedSet有序)
//b) 线性结构:一对一,数组
//c) 树形结构:一对多,菜单/文件夹/类别/树形控件/表达式目录树
//d) 图状结构(网状):多对多,地图/拓扑图/快递
//dnspy 反编译工具,反编译后可以改代码
//yield是语法糖,由编译器生成Iterator的代码,Current,MoveNext,Reset
//动态类型dynamic,framework4.0,弱类型特点;
//代替反射,不用反射找类的方法,属性了,直接写;数据绑定方便,Json序列化不用再定义类了
//任何东西和dynamic交互都变成dynamic了
//CollectionDemo.Show();
IteratorPattern.IteratorPattern.Show();
}
}
}
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace MyStructure
{
public class CollectionDemo
{
public static void Show()
{
//线性结构存储方式分两种:1在内存上连续分配,节约空间,比如数组
// 2非连续分配,每个元素存储数据和地址,查询只能顺序查找,读取慢增删快比如链表
//IEnumerable/ICollection/IList/IQueryble
//接口是标识功能的,不同的接口拆开,就是为了实现接口隔离,虽然我们的接口内容重复
//IEnumerable 任何数据集合,都实现这个接口,为了不同的数据结构,提供统一的访问方式,这个就是迭代器模式
#region Array
{
//Array在内存上连续分配,每个元素类型一样
//可以索引访问,读取快,增删慢,因为被影响的后续元素要位移
int[] intArray = new int[3];
intArray[0] = 1233;
string[] strArray = new string[] { "123", "345" };
}
{
//ArrayList 不定长,连续分配
//元素没有类型限制,任何元素都被当成object处理,如果是值类型,会有装箱操作
//现在已经逐渐废弃
ArrayList arrayList = new ArrayList();
arrayList.Add("小王");
arrayList.Add("小高");
arrayList.Add(18);
//arrayList[3] = 19;//会报错,只有add会增加数组长度,访问超出索引上限
var value = arrayList[2];
arrayList.RemoveAt(2);
arrayList.RemoveAt(0);
arrayList.Remove("小高");
}
{
//List 其实也是数组,内存上也是连续摆放,不定长;泛型,保证类型安全,避免装箱拆箱
List<int> intList = new List<int> { 1, 23, 4, 5 };
intList.Add(12);
intList.Add(23);
intList.Remove(23);//移除第一个
intList[0] = 11;
List<string> strList = new List<string> { "1", "2" };
strList[0] = "123";
}
#endregion
#region 链表
{
//LinkedList 泛型,链表,元素不连续分配, 实际应用:令牌环
//单向链表每个元素都记录下一个节点地址;双向记录上个和下个节点地址
//不能下表访问,找元素只能遍历
LinkedList<int> intLinkList = new LinkedList<int>();
intLinkList.AddFirst(123);
intLinkList.AddLast(123);
bool isContain = intLinkList.Contains(123);
LinkedListNode<int> node = intLinkList.Find(123);//相同值找第一个
intLinkList.AddBefore(node, 11);
intLinkList.AddBefore(node, 12);
intLinkList.AddAfter(node, 22);
intLinkList.Remove(12);
intLinkList.Remove(node);
intLinkList.RemoveFirst();
intLinkList.RemoveLast();
intLinkList.Clear();
}
{
//Queue 就是链表,先进先出,任务延迟执行,比如A不断将日志信息放入队列,B不断获取队列的信息输出
Queue<string> strQueue = new Queue<string>();
strQueue.Enqueue("one");
strQueue.Enqueue("two");
strQueue.Enqueue("three");
strQueue.Enqueue("four");
strQueue.Enqueue("five");
strQueue.Enqueue("six");
foreach (string str in strQueue)
{
Console.WriteLine(str);
}
Console.WriteLine($"Dequeue '{strQueue.Dequeue()}'");//移除第一个元素并返回
Console.WriteLine($"Peek '{strQueue.Peek()}'");//返回第一个元素
Console.WriteLine($"Dequeue '{strQueue.Dequeue()}'");
Queue<string> queueCopy = new Queue<string>(strQueue.ToArray());
foreach (string str in queueCopy)
{
Console.WriteLine(str);
}
Console.WriteLine($"queueCopy.Contains(\"four\"):{queueCopy.Contains("four")}");
Console.WriteLine($"queueCopy.Count ={queueCopy.Count}");
queueCopy.Clear();
}
{
Console.WriteLine("****************Stack<T>***************");
//Stack 就是链表,先进后出,解析表达式目录树的时候,先产生的数据后使用
//应用:撤销操作命令,最后一个先撤销
Stack<string> stack = new Stack<string>();
stack.Push("one");//第一个进去的,位置在最底部
stack.Push("two");
stack.Push("three");
stack.Push("four");
stack.Push("five");
stack.Push("six");
foreach (string str in stack)
{
Console.WriteLine(str);
}
Console.WriteLine($"Pop '{stack.Pop()}'");//移除最后一个元素并返回
Console.WriteLine($"Peek '{stack.Peek()}'");//返回第一个元素
Console.WriteLine($"Dequeue '{stack.Pop()}'");
var arr = stack.ToArray();
Stack<string> stackCopy = new Stack<string>(stack.ToArray());//栈的顺序和数组相反了,因为先进的排在后面
foreach (string str in stackCopy)
{
Console.WriteLine(str);
}
Console.WriteLine($"queueCopy.Contains(\"four\"):{stackCopy.Contains("four")}");
Console.WriteLine($"queueCopy.Count ={stackCopy.Count}");
stackCopy.Clear();
}
#endregion
#region 集合Set
{
Console.WriteLine("****************Set<T>***************");
//set仅仅是个集合,无序,但是元素具有唯一性
//hash分布,元素间没有关系,动态增加容量
//应用:统计IP/IP投票/二次好友/粉丝合集 交叉并补
HashSet<string> hashSet = new HashSet<string>();
hashSet.Add("one");
hashSet.Add("two");
hashSet.Add("three");
hashSet.Add("four");
hashSet.Add("five");
hashSet.Add("six");
hashSet.Add("six");
hashSet.Add("six");
foreach (var item in hashSet)
{
Console.WriteLine(item);
}
Console.WriteLine(hashSet.Count);
Console.WriteLine(hashSet.Contains("two"));
HashSet<string> hashSet1 = new HashSet<string>();
hashSet1.Add("four");
hashSet1.Add("five");
hashSet1.Add("six");
hashSet1.Add("seven");
hashSet1.Add("eight");
hashSet1.Add("nine");
hashSet1.Add("ten");
hashSet1.SymmetricExceptWith(hashSet);//对称差集
hashSet1.UnionWith(hashSet);//并
hashSet1.ExceptWith(hashSet);//差
hashSet1.IntersectWith(hashSet);//交
}
{
Console.WriteLine("****************SortedSet<T>***************");
//SortedSet 排序的集合,
//每进来一个元素都排一次序
//应用:排行榜
SortedSet<string> sortedSet = new SortedSet<string>();
//IComparer<T> comparer 自定义排序用这个,比较器
sortedSet.Add("123");
sortedSet.Add("12");
sortedSet.Add("1234");
sortedSet.Add("234");
sortedSet.Add("234");
foreach (var item in sortedSet)
{
Console.WriteLine(item);
}
Console.WriteLine(sortedSet.Count);
Console.WriteLine(sortedSet.Contains("two"));
}
#endregion
#region Key--Value
{
Console.WriteLine("****************Hashtable***************");
//Hashtable,key-value读取快,增删也快,基于数组实现的
//体积动态增加,拿key散列计算得到一个地址索引,数据存储在这个地址上,
//如果有数据(散列冲突)地址+1;数据量不宜太大(3W条?),避免散列冲突太多
//删除时也是计算出地址,直接对这个地址操作
//空间有浪费;空间换时间
//装箱拆箱
Hashtable hashtable = new Hashtable();
hashtable.Add("123", "小王");
hashtable[234] = 999;
hashtable[234] = 888;
hashtable[21] = 66;
hashtable["xiaowang"] = "小高";
foreach (DictionaryEntry item in hashtable)
{
Console.WriteLine(item.Key.ToString() + "--" + item.Value.ToString());
}
//线程安全
Hashtable safeHashtable = Hashtable.Synchronized(hashtable);//一个线程写,多个线程读
}
{
Console.WriteLine("****************Dictionary<T,T>***************");
//字典 泛型,字典不是线程安全的,线程安全是:ConcurrentDictionary
Dictionary<int, string> dic = new Dictionary<int, string>();
dic.Add(1, "123");
dic.Add(5, "13");
dic.Add(4, "3");
dic.Add(2, "12");
dic.Add(3, "1");
dic[4] = "小王";
foreach (var item in dic)
{
Console.WriteLine(item.Key + "--" + item.Value);
}
}
{
Console.WriteLine("****************SortedDictionary<T,T>***************");
//SortedDictionary字典 有序的字典
SortedDictionary<int, string> dic = new SortedDictionary<int, string>();
dic.Add(1, "123");
dic.Add(5, "13");
dic.Add(4, "3");
dic.Add(2, "12");
dic.Add(3, "1");
dic[4] = "小王";
foreach (var item in dic)
{
Console.WriteLine(item.Key + "--" + item.Value);
}
}
{
Console.WriteLine("****************SortedList<T,T>***************");
SortedList<string, string> sortedList = new SortedList<string, string>();
sortedList.Add("First", "Hello");
sortedList.Add("Second", "World");
sortedList.Add("Third", "!");
sortedList["Third"] = "!!!";
//sortedList.Add("Forth", "==");//add相同的可以报错
sortedList.Add("Forth", "--");
sortedList["Forth"] = "--";
sortedList["Fifth"] = "//";
var keyList = sortedList.Keys;
var valueList = sortedList.Values;
sortedList.TrimExcess();//减少内存开销
sortedList.Remove("Third");
sortedList.RemoveAt(0);
sortedList.Clear();
}
#endregion
#region 线程安全版本
//ConcurrentQueue
//ConcurrentStack
//ConcurrentDictionary
//ConcurrentBag<int> ts = new ConcurrentBag<int> { 1, 2, 3 }; //集合
//BlockingCollection
#endregion
}
}
}
using IteratorPattern.Iterator;
using IteratorPattern.Menu;
using System;
using System.Collections.Generic;
namespace IteratorPattern
{
public class IteratorPattern
{
//1 迭代器模式 Iterator
//2 .net的迭代器模式 yield return
//3 延迟查询,按需获取
public static void Show()
{
//KFC和MacDonal 两者的Foods数据结构差不多,都是集合,但是获取foods值的方式却不一样
//一个是length,一个是count。我们更希望两者有共同的方式获取值
//类似于数组和List都能foreach一样,数组和list都实现了迭代器
//我们实现个类似于迭代器一样的东西,可以供KFC和MacDonal以共同方式遍历Foods
{
Console.WriteLine("********************KFC***********************");
KFCMenu menu = new KFCMenu();
Food[] foods = menu.GetFoods();
for (int i = 0; i < foods.Length; i++)
{
Console.WriteLine($"KFC:Id={foods[i].Id} Name={foods[i].Name} Price={foods[i].Price}");
}
foreach (var item in foods)
{
Console.WriteLine($"KFC:Id={item.Id} Name={item.Name} Price={item.Price}");
}
//相同的遍历方式
IIterator<Food> iterator = menu.GetEnumerator();
while (iterator.MoveNext())
{
Console.WriteLine($"KFC:Id={iterator.Current.Id} Name={iterator.Current.Name} Price={iterator.Current.Price}");
}
}
{
Console.WriteLine("********************MacDonal***********************");
MacDonalMenu menu = new MacDonalMenu();
List<Food> foods = menu.GetFoods();
for (int i = 0; i < foods.Count; i++)
{
Console.WriteLine($"KFC:Id={foods[i].Id} Name={foods[i].Name} Price={foods[i].Price}");
}
foreach (var item in foods)
{
Console.WriteLine($"KFC:Id={item.Id} Name={item.Name} Price={item.Price}");
}
IIterator<Food> iterator = menu.GetEnumerator();
while (iterator.MoveNext())
{
Console.WriteLine($"KFC:Id={iterator.Current.Id} Name={iterator.Current.Name} Price={iterator.Current.Price}");
}
}
}
}
}
using IteratorPattern.Iterator;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Menu
{
public class KFCMenu
{
private Food[] foods = new Food[3];
public KFCMenu()
{
foods[0] = new Food()
{
Id = 1,
Name = "汉堡",
Price = 10
};
foods[1] = new Food()
{
Id = 1,
Name = "可乐",
Price = 8
};
foods[2] = new Food()
{
Id = 1,
Name = "薯条",
Price = 5
};
}
public Food[] GetFoods()
{
return this.foods;
}
public IIterator<Food> GetEnumerator()
{
return new KFCMenuIterator(this);
}
}
}
using IteratorPattern.Iterator;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Menu
{
public class MacDonalMenu
{
private List<Food> foods = new List<Food>();
public MacDonalMenu()
{
foods.Add(new Food()
{
Id = 1,
Name = "鸡腿",
Price = 10
});
foods.Add(new Food()
{
Id = 1,
Name = "冰淇淋",
Price = 10
});
foods.Add(new Food()
{
Id = 1,
Name = "鸡翅",
Price = 10
});
}
public List<Food> GetFoods()
{
return this.foods;
}
public IIterator<Food> GetEnumerator()
{
return new MacDonalMenuIterator(this);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Iterator
{
public interface IIterator<T>
{
/// <summary>
/// 当前对象
/// </summary>
T Current { get; }
/// <summary>
/// 移动到下个对象,是否存在
/// </summary>
/// <returns></returns>
bool MoveNext();
/// <summary>
/// 重置
/// </summary>
void Reset();
}
}
using IteratorPattern.Menu;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Iterator
{
public class KFCMenuIterator : IIterator<Food>
{
private Food[] foods = null;
public KFCMenuIterator(KFCMenu menu)
{
this.foods = menu.GetFoods();
}
private int _CurrentIndex = -1;
/// <summary>
/// 当前对象
/// </summary>
public Food Current
{
get
{
return this.foods[_CurrentIndex];
}
}
/// <summary>
/// 移动到下个对象,是否存在
/// </summary>
/// <returns></returns>
public bool MoveNext()
{
return foods.Length > ++_CurrentIndex;
}
/// <summary>
/// 重置
/// </summary>
public void Reset()
{
_CurrentIndex = -1;
}
}
}
using IteratorPattern.Menu;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Iterator
{
public class MacDonalMenuIterator : IIterator<Food>
{
private List<Food> foods = null;
public MacDonalMenuIterator(MacDonalMenu menu)
{
this.foods = menu.GetFoods();
}
private int _CurrentIndex = -1;
/// <summary>
/// 当前对象
/// </summary>
public Food Current
{
get
{
return this.foods[_CurrentIndex];
}
}
/// <summary>
/// 移动到下个对象,是否存在
/// </summary>
/// <returns></returns>
public bool MoveNext()
{
return foods.Count > ++_CurrentIndex;
}
/// <summary>
/// 重置
/// </summary>
public void Reset()
{
_CurrentIndex = -1;
}
}
}