c#list集合
·
1.自己实习find功能
// Array.Find()
int[] ages = new int[] {1,2,3,4,5};
// Console.WriteLine(ages[10]); //System.IndexOutOfRangeException: 索引超出了数组界限。
//调用自己的Find方法
//参数1:整型的数组
//参数2:func类型的函数 v => v % 2 == 0
// Console.WriteLine(MyArray.Find(ages, v => v % 2 == 0));
//DivideByZeroException: 尝试除以零。
//int a = 10;
//Console.WriteLine(a/0);
Console.WriteLine(MyArray.Find(ages, v => v % 2 == 0));
Console.WriteLine(MyArray.Find(ages, v => v % 3 == 0));
}
}
public class MyArray
{
//arr 就是 int[] ages = new int[] { 1, 2, 3 };
//match 就是 v => v % 2 == 0 函数必须调用
public static int Find(int[] arr, Func<int, bool> match) //match 函数, 必须调用
{
if (arr == null)
{
throw new ArgumentNullException("array");
}
if (match == null)
{
throw new ArgumentNullException("match");
}
for (int i = 0; i < arr.Length; i++) //遍历每一个元素,判断元素是否满足match函数
{
if (match(arr[i])) // 调用v => v % 2 == 0函数 ,v就是arr【i】 就是每一个元素
{
return arr[i];//返回元素本身
}
}
return 0; //没找到话 返回默认值0
}
2.冒泡排序
//冒泡排序,Bubble Sort 一个简单且常用的排序算法。因最大或最小的元素会经过交换慢慢出现在数列顶端,好似元素冒出来一样,得名“冒泡排序”。
//原理
//1. * *比较相邻元素 * *:从列表的第一个元素开始,比较相邻的两个元素
//2. * *交换位置 * *:如果前一个元素比后一个元素大(升序排序时),就交换它们的位置
//3. * *重复遍历 * *:对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对
//4. * *最大元素沉底 * *:每次完整遍历后,最大的元素会"冒泡"到列表的末尾
//5. * *缩小范围 * *:忽略已经排序好的末尾部分,重复上述过程
//6. * *完成排序 * *:当没有元素需要交换时,排序完成
int[] num = { 1, 2, 3,10, 5, 7, 8, 33, 9 };
//未优化
//外循环的循环次数0开始到长度为止,
//取出数组每一个元素
for (int i = 0; i < num.Length; i++)
{
//内循环控制比较次数,最大次数减1
//假设9个数,比较8次
for (global::System.Int32 j = 0; j < num.Length-1; j++)
{
//ints1.Length===9 j最大 是 8 但是 j+1==9 索引越界
if (num[j] > num[j+1]) //num[j]前面数; num[j+1]后面的数
{
//交换位置
(num[j], num[j+1]) = (num[j+1], num[j]);
}
}
}
Console.WriteLine(string.Join("-",num));
//优化版
for (int i = 0; i < num.Length; i++)
{
//-1的原因: ints1.Length===8 j最大 是 7 但是 j+1==8 索引越界
//-i的原因 : 每次循环都会多一组排序好的值,让内层循环每执行一次,就少一次
for (int j = 0; j < num.Length - 1 - i; j++)
{
if (num[j] > num[j + 1])
{
//语法糖交换位置
(num[j], num[j + 1]) = (num[j + 1], num[j]);
}
}
}
Console.WriteLine(string.Join("-", num));
3.选择排序
/*
int[] nums = { 1, 2, 30, 4, 5, 8, 8, 8, 9 };
for (int i = 0; i < nums.Length; i++)
{
int minIndex = i;// 目前最小值的索引的i, 例如i=0
for (int j = i+1; j < nums.Length; j++)
{
if (nums[j] < nums[minIndex]) // nums[minIndex] 最小值 ;nums[j]数组里面后面元素
//nums[j]是小值 把小值的索引值赋值给minIndex
{
minIndex = j;
}
}
if (minIndex!=i)
{
//交换位置nums[minIndex]
(nums[i], nums[minIndex]) = (nums[minIndex], nums[i]);
}
}
Console.WriteLine( string.Join("-",nums));
*/
int[] nums = { 1, 2, 30, 4, 5, 8, 8, 8, 9 };
// Array.Sort(nums);// 默认的是升序排序, 从小到大的排序
//Array.Reverse(nums);// 颠倒数组的元素的顺序
//Console.WriteLine(string.Join("-", nums));
//第二种排序写法
//Array.Sort(nums, (x, y) => { return x - y; });//升序排序
//Console.WriteLine(string.Join("-", nums));
//Array.Sort(nums, (x, y) => { return y - x; });//降序排序
//Console.WriteLine(string.Join("-", nums));
//第三种排序写法
Array.Sort(nums, (x, y) =>
{
if (x < y) return -1; // x 比 y 小 → x 放前面
if (x > y) return 1; // x 比 y 大 → x 放后面
return 0; // 相等 → 不动
});
Console.WriteLine(string.Join("-", nums));
4.ArrayList动态集合
//理解
//ArrayList实现了IList, ICollection, IEnumerable, ICloneable接口
//IList:List列表,主要负责集合的插入,添加,删除,取索引,判断是否包含某个项等操作。
//ICollection:Collection集合。主要负责集合中的项的个数,集合的复制,拷贝等。
//IEnumerable:Enumerable可枚举的; 可数的,可枚举的。主要实现迭代器,实现此接口类都可以被循环,被遍历,被迭代,被枚举
// ICloneable:Cloneable克隆,主要负责集合的克隆(复制,拷贝),了解和ICollection接口中CopyTo()的区别:https://blog.csdn.net/yao_hou/article/details/134484811
int[] ages = new int[] {1,2,3,4,5};
//ArrayList直接继承object
//int[] 继承于Array 继承于Object
//区别 :1ArrayList定义完之后数组的长度可以动态添加 ,int[]一旦定义完之后 长度是固定的,
//2 ArrayList存储的是对象类型, int[]数组只能存储相同类型的数据
//3 ArrayList存取数据出现装箱、拆箱操作, int[] 不用装箱和拆箱
//4 ArrayList存储数据类型不安全, int[]数据类型安全
ArrayList list = new ArrayList() { 1, 2, 3, true, "ss", new object() };
Console.WriteLine(list.GetType().BaseType);//System.Object
ArrayList list1 = new ArrayList(); //创建一个动态集合对象
//1添加元素 把1转成对象类型之后 再添加到动态集合里面,
//把值类型转成引用类型的过程,就是装箱操作
list1.Add(1);
list1.Add(2);
list1.Add(3);
//3 AddRange() 添加一个范围 可以添加一个数组类型的数据. 也可以添加一个集合类型数据
// list1.AddRange(ages);
// list1.AddRange(list);
//2取出元素 通过索引值取出元素值
Console.WriteLine(list1[0]);//1
//list1[0]本身一个对象,需要转成值类型,这个过程就是拆箱
Console.WriteLine((int)list1[0]);
//4 Contains 是否包含某个元素
Console.WriteLine(list1.Contains(1));//true
//5 IndexOf() 获取某个元素的索引值
Console.WriteLine(list1.IndexOf(1));
// 6 remove() 移除指定元素
list1.Remove(1);
//RemoveAt移除指定位置的元素
list1.RemoveAt(0);
//7 修改
list1[0] = "张三";
//8 Insert()在指定位置添加一个元素
list1.Insert(0, "李四");
//在指定位置添加一个范围数据
list1.InsertRange(2, ages);
//9清空集合
//list1.Clear();
//10LastIndexOf 找索引值 从后往前找
Console.WriteLine(list1.LastIndexOf("李四"));
//11 颠倒数组的元素
// list1.Reverse();
//12 GetRange 从源集合取出一个子集, 参数1从指定位置开始,参数2截取的长度
ArrayList list2 = list1.GetRange(0, 3);
// getRange() 不是独立列表 是原列表的试图,通过setRange修改原列表,再去遍历子列表会报错
// setRange()设置指定范围的数据
list1.SetRange(0, new int[] { 9999, 888 }); //基础列表中的该范围无效。一个可能的原因是元素被移除。
//如果添加list1.SetRange()这一句 ,下面的for出现报错
//foreach (var item in list2)
//{
// Console.WriteLine(item+"??????");
//}
//for遍历
//list1.Count 集合数据个数
//for (int i = 0; i < list1.Count; i++)
//{
// Console.WriteLine(list1[i]);
//}
foreach (var item in list1)
{
Console.WriteLine(item + "------");
}
5.泛型集合
//List<>:泛型集合,可以传入类型存储相同类型的数据,不存在装箱或者拆箱的过程
List<int> list = new List<int>();
List<string> list1 = new List<string> { "李张三", "李四" };
Console.WriteLine(list1.Count);//个数
//1添加元素
list1.Add("1");
list1.AddRange(new List<string> { "王五" });
//2 移除指定元素
//list1.Remove("1") ;
//list1.RemoveAt(0) ;//移除指定位置的元素
//RemoveAll() 移除指定条件的元素 返回值移除个数
//Console.WriteLine(list1.RemoveAll(v => v.StartsWith("李")));
// 3 修改通过索引值进行修改
list1[2] = "焦恩俊";
//4 插入
list1.Insert(4, "何家劲");
//list1.IndexOf("1") ; // 获取指定元素的索引值
//List里面的高阶函数和数组当中高阶函数大部分都一样,只不过数组采用类名调用,List采用的是对象调用
//list1.ForEach(x => Console.WriteLine(x));
//list1.Contains() 是否包含元素
foreach (var i in list1)
{
Console.WriteLine(i + "-------");
}
6.字典
//字典: Dictionary<>,包含键(key)值(value)对.
//key键是唯一的,类似于数组的下标,数组下标只能整型,但是key可以任意类型
//value值是根据键去取
//定义一个字典
//int 是键的类型
//string 值的类型
Dictionary<int, string> dic = new Dictionary<int, string>();
//添加键值对
dic.Add(0, "何润东");//参数1是键 ,参数2是值
dic.Add(1, "周传雄-情歌教父");
//根据键取值
Console.WriteLine(dic[0]);
Console.WriteLine(dic.Keys);//获取所有的键
//一般直接使用dic.Keys 和 dic.Values 不用再去定义一个变量去接收
// Dictionary<int,string>.KeyCollection keys = dic.Keys;
// Dictionary<int,string>.ValueCollection values = dic.Values;
dic.Remove(0); //指定键移除键值对
Console.WriteLine(dic.Count);//键值对的个数
Console.WriteLine(dic.ContainsKey(0)); //判断是否包含某个键
// dic.Clear(); //清空键值对
//遍历所有键
foreach (var item in dic.Keys)
{
Console.WriteLine(item + "----"); //每一个key
//Console.WriteLine(dic[item]); // 根据key获取值
}
//遍历字典所有的值
foreach (var item in dic.Values) // dic.Values 获取所有的值
{
Console.WriteLine(item + "++++");
}
//遍历整个字典
foreach (var item in dic)
{
Console.WriteLine(item.Key + ":" + item.Value);
}
//使用for循环遍历所有的值 dic.values 不能使用dic.Values[i]这种方式进行访问,需要转成数组之后再能使用[]方式访问
//但是字典dic[key]访问值
//for (int i = 0; i < dic.Values.Count; i++)
//{
// Console.WriteLine(dic.Values.ToArray()[i]+"sss");
//}
//定义一个字典 键是班级的名字 值是一个班学员姓名数组
Dictionary<string, string[]> dic1 = new Dictionary<string, string[]>()
{
{"一班", new string[]{ "马化腾","马云","马斯克"} },//键值对
{"二班", new string[]{ "焦恩俊","严屹宽","霍建华","乔振宇"} }
};
string[] arr = dic1["一班"];
Console.WriteLine(string.Join("-", arr));
7.hashTable 哈希表
static void Main(string[] args)
{
//C# 中的Hashtable是.NET 早期非泛型键值对哈希集合,基于哈希算法实现快速查找,存在装箱拆箱、类型不安全问题,现已被泛型Dictionary替代。
//. 核心原理:放入数据给一个 Key 和 Value,通过哈希函数把 Key 转换成一个数字(哈希码) ,根据这个数字直接定位存储位
Hashtable hashtable = new Hashtable()
{
{1,"这是1" },
{true,"这是true" }
};
//1.Add()添加键值对
hashtable.Add(0, "这是0");
hashtable.Add(2, new int[] {1,2,3});
//2.哈希表键值对个数
Console.WriteLine(hashtable.Count);
//3.取值
Console.WriteLine(hashtable[1]);
//4.修改
hashtable[1] = 100;
Console.WriteLine(hashtable[1]);
//5.所有的keys的
Console.WriteLine(hashtable.Keys);
//6.所有的values
Console.WriteLine(hashtable.Values);
//7.遍历所有值
foreach (var item in hashtable.Values)
{
Console.WriteLine(item+"---");
}
//8.移除键值对
hashtable.Remove(0);
//hashtable.Clear();
//9.包含
Console.WriteLine(hashtable.ContainsKey(0));
}
8.sortList有序列表
static void Main(string[] args)
{
//sortList:通过键进行排序的列表,存储的是键值对
SortedList list = new SortedList()
{
{13,"秦琼" },
{10,"罗成" },
{3,"裴元庆" },
{2,"宇文成都" },
{1,"李元霸" },
//{"a","ss" }"a"与数字无法比较
};
//添加键值对
list.Add(4, "熊阔海");
//修改键值对
list[10] = "杨林";
//按照键删除
list.Remove(4);
//按照索引删除
list.RemoveAt(3);
//list.Clear(); 全部删除
//Console.WriteLine(list.Keys);
//Console.WriteLine(list.Values);
//GetByIndex(0) 通过索引值取值
//如果索引值为0,值是键最小的键值对
Console.WriteLine(list.GetByIndex(0));
Console.WriteLine(list.GetByIndex(1));
//GetKey 获取键 按照索引值
//写成0 键是1
Console.WriteLine(list.GetKey(0));
//GetValueList 获取所有值
for (int i = 0; i < list.GetValueList().Count; i++)
{
Console.WriteLine(list.GetValueList()[i]+"-----");
}
//遍历
foreach (var item in list.Values)
{
Console.WriteLine(item+"+++");
}
}
9.栈和队列
static void Main(string[] args)
{
//栈:存储数据的容器,特点先入后出的,添加一个元素叫入栈,删除一个元素叫出栈
Stack<int> stack = new Stack<int>();//泛型的定义方式
Stack stack1 = new Stack();//非泛型的定义方式
stack1.Push("张三");//入栈 栈底
stack1.Push("李四");
stack1.Push("王五");
Console.WriteLine(stack1.Pop());//Pop() 删除并返回栈顶对象,王五
Console.WriteLine(stack1.Peek());//Peek() 返回栈顶对象,李四
for (int i = 0; i < stack1.Count; i++)
{
Console.WriteLine(stack1.ToArray()[i]);
}
foreach (var item in stack1)
{
Console.WriteLine(item+"---");
}
//stack.Clear();
//stack.Contains(0);
//队列的特点:先入先出的特点 添加一个元素叫入队,删除一个元素叫出队
Queue<string> queue = new Queue<string>();
queue.Enqueue("hello1");//入队
queue.Enqueue("hello2");
queue.Enqueue("hello3");
Console.WriteLine(queue.Dequeue());//移除一个对象 并返回第一个开始的对象 hello1
Console.WriteLine(queue.Peek());//hello2
foreach (var item in queue)
{
Console.WriteLine(item);
}
}
### Queue 类中的方法
下表列出了 Queue 类的一些常用的方法:
| 方法名 | 描述 |
|---|---|
| public virtual void Clear() | 从队列中移除所有的元素 |
| public virtual bool Contains(object obj) | 判断某个元素是否在队列中 |
| public virtual object Dequeue() | 移除并返回在队列开头的对象 |
| public virtual void Enqueue(object obj) | 向队列的末尾处添加一个对象 |
| public virtual object[] ToArray() | 复制队列到一个新的数组中 |
| public virtual void TrimToSize() | 将队列的容量设置为队列中元素的实际个数 |
更多推荐
所有评论(0)