1. 数组基础
1.1 数组的声明和初始化
using System;
using System.Linq;
public class ArrayBasics
{
public static void Main()
{
Console.WriteLine("=== 数组基础 ===");
// 数组声明和初始化的不同方式
DemonstrateArrayDeclaration();
// 数组操作
DemonstrateArrayOperations();
// 多维数组
DemonstrateMultidimensionalArrays();
// 锯齿数组
DemonstrateJaggedArrays();
}
private static void DemonstrateArrayDeclaration()
{
Console.WriteLine("\n--- 数组声明和初始化 ---");
// 方式1:声明后初始化
int[] numbers1 = new int[5]; // 创建长度为5的数组,默认值为0
numbers1[0] = 10;
numbers1[1] = 20;
numbers1[2] = 30;
numbers1[3] = 40;
numbers1[4] = 50;
Console.WriteLine($"numbers1: [{string.Join(", ", numbers1)}]");
// 方式2:声明时初始化
int[] numbers2 = new int[] { 1, 2, 3, 4, 5 };
Console.WriteLine($"numbers2: [{string.Join(", ", numbers2)}]");
// 方式3:简化语法
int[] numbers3 = { 10, 20, 30, 40, 50 };
Console.WriteLine($"numbers3: [{string.Join(", ", numbers3)}]");
// 方式4:使用var关键字
var numbers4 = new[] { 100, 200, 300, 400, 500 };
Console.WriteLine($"numbers4: [{string.Join(", ", numbers4)}]");
// 字符串数组
string[] names = { "Alice", "Bob", "Charlie", "David" };
Console.WriteLine($"names: [{string.Join(", ", names)}]");
// 布尔数组
bool[] flags = new bool[] { true, false, true, false };
Console.WriteLine($"flags: [{string.Join(", ", flags)}]");
// 数组属性
Console.WriteLine($"\n数组属性:");
Console.WriteLine($"numbers1.Length: {numbers1.Length}");
Console.WriteLine($"numbers1.Rank: {numbers1.Rank}");
Console.WriteLine($"numbers1.GetType(): {numbers1.GetType()}");
}
private static void DemonstrateArrayOperations()
{
Console.WriteLine("\n--- 数组操作 ---");
int[] numbers = { 5, 2, 8, 1, 9, 3 };
Console.WriteLine($"原始数组: [{string.Join(", ", numbers)}]");
// 访问元素
Console.WriteLine($"第一个元素: {numbers[0]}");
Console.WriteLine($"最后一个元素: {numbers[numbers.Length - 1]}");
// 修改元素
numbers[0] = 100;
Console.WriteLine($"修改后: [{string.Join(", ", numbers)}]");
// 遍历数组
Console.WriteLine("\n使用for循环遍历:");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine($"numbers[{i}] = {numbers[i]}");
}
Console.WriteLine("\n使用foreach循环遍历:");
foreach (int number in numbers)
{
Console.WriteLine($"值: {number}");
}
// 数组方法
Console.WriteLine("\n--- 数组方法 ---");
// 查找
int index = Array.IndexOf(numbers, 8);
Console.WriteLine($"数字8的索引: {index}");
bool contains = Array.Exists(numbers, x => x > 50);
Console.WriteLine($"是否包含大于50的数字: {contains}");
// 排序
int[] sortedNumbers = (int[])numbers.Clone();
Array.Sort(sortedNumbers);
Console.WriteLine($"排序后: [{string.Join(", ", sortedNumbers)}]");
// 反转
int[] reversedNumbers = (int[])numbers.Clone();
Array.Reverse(reversedNumbers);
Console.WriteLine($"反转后: [{string.Join(", ", reversedNumbers)}]");
// 复制
int[] copiedNumbers = new int[numbers.Length];
Array.Copy(numbers, copiedNumbers, numbers.Length);
Console.WriteLine($"复制的数组: [{string.Join(", ", copiedNumbers)}]");
// 清空
Array.Clear(copiedNumbers, 0, copiedNumbers.Length);
Console.WriteLine($"清空后: [{string.Join(", ", copiedNumbers)}]");
}
private static void DemonstrateMultidimensionalArrays()
{
Console.WriteLine("\n--- 多维数组 ---");
// 二维数组
int[,] matrix = new int[3, 4];
// 初始化二维数组
int value = 1;
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i, j] = value++;
}
}
Console.WriteLine("二维数组 (3x4):");
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write($"{matrix[i, j],3} ");
}
Console.WriteLine();
}
// 直接初始化二维数组
int[,] matrix2 = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
Console.WriteLine("\n预初始化的二维数组:");
for (int i = 0; i < matrix2.GetLength(0); i++)
{
for (int j = 0; j < matrix2.GetLength(1); j++)
{
Console.Write($"{matrix2[i, j],3} ");
}
Console.WriteLine();
}
// 三维数组
int[,,] cube = new int[2, 3, 4];
Console.WriteLine($"\n三维数组维度: {cube.GetLength(0)} x {cube.GetLength(1)} x {cube.GetLength(2)}");
Console.WriteLine($"三维数组总元素数: {cube.Length}");
}
private static void DemonstrateJaggedArrays()
{
Console.WriteLine("\n--- 锯齿数组 ---");
// 锯齿数组(数组的数组)
int[][] jaggedArray = new int[3][];
// 为每一行分配不同长度的数组
jaggedArray[0] = new int[4] { 1, 2, 3, 4 };
jaggedArray[1] = new int[2] { 5, 6 };
jaggedArray[2] = new int[3] { 7, 8, 9 };
Console.WriteLine("锯齿数组:");
for (int i = 0; i < jaggedArray.Length; i++)
{
Console.Write($"行 {i}: ");
for (int j = 0; j < jaggedArray[i].Length; j++)
{
Console.Write($"{jaggedArray[i][j]} ");
}
Console.WriteLine();
}
// 直接初始化锯齿数组
int[][] jaggedArray2 = {
new int[] { 10, 20 },
new int[] { 30, 40, 50, 60 },
new int[] { 70 }
};
Console.WriteLine("\n预初始化的锯齿数组:");
for (int i = 0; i < jaggedArray2.Length; i++)
{
Console.WriteLine($"行 {i}: [{string.Join(", ", jaggedArray2[i])}]");
}
// 锯齿数组 vs 多维数组的区别
Console.WriteLine("\n--- 锯齿数组 vs 多维数组 ---");
// 多维数组:所有行必须有相同的列数
int[,] rectangular = new int[2, 3];
Console.WriteLine($"多维数组大小: {rectangular.GetLength(0)} x {rectangular.GetLength(1)}");
// 锯齿数组:每行可以有不同的列数
int[][] jagged = new int[2][];
jagged[0] = new int[3];
jagged[1] = new int[5];
Console.WriteLine($"锯齿数组行数: {jagged.Length}");
Console.WriteLine($"第0行列数: {jagged[0].Length}");
Console.WriteLine($"第1行列数: {jagged[1].Length}");
}
}
1.2 数组的高级操作
using System;
using System.Linq;
public class AdvancedArrayOperations
{
public static void Main()
{
Console.WriteLine("=== 数组高级操作 ===");
// LINQ操作
DemonstrateLINQOperations();
// 数组算法
DemonstrateArrayAlgorithms();
// 数组性能优化
DemonstratePerformanceOptimizations();
}
private static void DemonstrateLINQOperations()
{
Console.WriteLine("\n--- LINQ数组操作 ---");
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Console.WriteLine($"原始数组: [{string.Join(", ", numbers)}]");
// 过滤
var evenNumbers = numbers.Where(x => x % 2 == 0).ToArray();
Console.WriteLine($"偶数: [{string.Join(", ", evenNumbers)}]");
var greaterThanFive = numbers.Where(x => x > 5).ToArray();
Console.WriteLine($"大于5的数: [{string.Join(", ", greaterThanFive)}]");
// 转换
var squares = numbers.Select(x => x * x).ToArray();
Console.WriteLine($"平方: [{string.Join(", ", squares)}]");
var doubled = numbers.Select(x => x * 2).ToArray();
Console.WriteLine($"翻倍: [{string.Join(", ", doubled)}]");
// 聚合操作
int sum = numbers.Sum();
double average = numbers.Average();
int min = numbers.Min();
int max = numbers.Max();
int count = numbers.Count();
Console.WriteLine($"\n聚合操作:");
Console.WriteLine($"总和: {sum}");
Console.WriteLine($"平均值: {average:F2}");
Console.WriteLine($"最小值: {min}");
Console.WriteLine($"最大值: {max}");
Console.WriteLine($"元素个数: {count}");
// 条件检查
bool hasEven = numbers.Any(x => x % 2 == 0);
bool allPositive = numbers.All(x => x > 0);
bool containsFive = numbers.Contains(5);
Console.WriteLine($"\n条件检查:");
Console.WriteLine($"包含偶数: {hasEven}");
Console.WriteLine($"全部为正数: {allPositive}");
Console.WriteLine($"包含数字5: {containsFive}");
// 排序和分组
var sortedDesc = numbers.OrderByDescending(x => x).ToArray();
Console.WriteLine($"降序排列: [{string.Join(", ", sortedDesc)}]");
var grouped = numbers.GroupBy(x => x % 3)
.Select(g => new { Remainder = g.Key, Numbers = g.ToArray() })
.ToArray();
Console.WriteLine("\n按除以3的余数分组:");
foreach (var group in grouped)
{
Console.WriteLine($"余数 {group.Remainder}: [{string.Join(", ", group.Numbers)}]");
}
// 取前几个和跳过几个
var firstThree = numbers.Take(3).ToArray();
var skipTwo = numbers.Skip(2).ToArray();
var middleThree = numbers.Skip(3).Take(3).ToArray();
Console.WriteLine($"\n前3个: [{string.Join(", ", firstThree)}]");
Console.WriteLine($"跳过前2个: [{string.Join(", ", skipTwo)}]");
Console.WriteLine($"中间3个: [{string.Join(", ", middleThree)}]");
}
private static void DemonstrateArrayAlgorithms()
{
Console.WriteLine("\n--- 数组算法 ---");
int[] numbers = { 64, 34, 25, 12, 22, 11, 90 };
Console.WriteLine($"原始数组: [{string.Join(", ", numbers)}]");
// 冒泡排序
int[] bubbleSorted = (int[])numbers.Clone();
BubbleSort(bubbleSorted);
Console.WriteLine($"冒泡排序: [{string.Join(", ", bubbleSorted)}]");
// 选择排序
int[] selectionSorted = (int[])numbers.Clone();
SelectionSort(selectionSorted);
Console.WriteLine($"选择排序: [{string.Join(", ", selectionSorted)}]");
// 插入排序
int[] insertionSorted = (int[])numbers.Clone();
InsertionSort(insertionSorted);
Console.WriteLine($"插入排序: [{string.Join(", ", insertionSorted)}]");
// 二分查找(需要已排序的数组)
Array.Sort(numbers);
Console.WriteLine($"已排序数组: [{string.Join(", ", numbers)}]");
int target = 25;
int index = BinarySearch(numbers, target);
Console.WriteLine($"二分查找 {target}: 索引 {index}");
// 数组反转
int[] original = { 1, 2, 3, 4, 5 };
int[] reversed = ReverseArray(original);
Console.WriteLine($"原数组: [{string.Join(", ", original)}]");
Console.WriteLine($"反转后: [{string.Join(", ", reversed)}]");
// 数组旋转
int[] toRotate = { 1, 2, 3, 4, 5, 6, 7 };
int[] rotated = RotateArray(toRotate, 3);
Console.WriteLine($"原数组: [{string.Join(", ", toRotate)}]");
Console.WriteLine($"右旋转3位: [{string.Join(", ", rotated)}]");
// 查找最大子数组和(Kadane算法)
int[] subArrayTest = { -2, -3, 4, -1, -2, 1, 5, -3 };
int maxSum = MaxSubArraySum(subArrayTest);
Console.WriteLine($"数组: [{string.Join(", ", subArrayTest)}]");
Console.WriteLine($"最大子数组和: {maxSum}");
}
private static void BubbleSort(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
// 交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
private static void SelectionSort(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
int minIndex = i;
for (int j = i + 1; j < n; j++)
{
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
}
// 交换
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
private static void InsertionSort(int[] arr)
{
int n = arr.Length;
for (int i = 1; i < n; i++)
{
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
private static int BinarySearch(int[] arr, int target)
{
int left = 0;
int right = arr.Length - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == target)
return mid;
if (arr[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return -1; // 未找到
}
private static int[] ReverseArray(int[] arr)
{
int[] result = new int[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
result[i] = arr[arr.Length - 1 - i];
}
return result;
}
private static int[] RotateArray(int[] arr, int k)
{
int n = arr.Length;
k = k % n; // 处理k大于数组长度的情况
int[] result = new int[n];
// 将后k个元素移到前面
for (int i = 0; i < k; i++)
{
result[i] = arr[n - k + i];
}
// 将前n-k个元素移到后面
for (int i = 0; i < n - k; i++)
{
result[k + i] = arr[i];
}
return result;
}
private static int MaxSubArraySum(int[] arr)
{
int maxSoFar = arr[0];
int maxEndingHere = arr[0];
for (int i = 1; i < arr.Length; i++)
{
maxEndingHere = Math.Max(arr[i], maxEndingHere + arr[i]);
maxSoFar = Math.Max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
private static void DemonstratePerformanceOptimizations()
{
Console.WriteLine("\n--- 性能优化技巧 ---");
// 预分配数组大小
Console.WriteLine("1. 预分配数组大小");
// 不好的做法:频繁调整大小
var dynamicList = new System.Collections.Generic.List<int>();
for (int i = 0; i < 1000; i++)
{
dynamicList.Add(i);
}
// 好的做法:预分配容量
var preallocatedList = new System.Collections.Generic.List<int>(1000);
for (int i = 0; i < 1000; i++)
{
preallocatedList.Add(i);
}
Console.WriteLine("预分配容量可以减少内存重新分配的次数");
// 使用Span<T>进行高性能操作
Console.WriteLine("\n2. 使用Span<T>进行高性能操作");
int[] largeArray = new int[1000];
for (int i = 0; i < largeArray.Length; i++)
{
largeArray[i] = i;
}
// 使用Span避免数组复制
Span<int> span = largeArray.AsSpan(100, 50); // 从索引100开始的50个元素
// 对span进行操作,不会复制数据
for (int i = 0; i < span.Length; i++)
{
span[i] *= 2;
}
Console.WriteLine($"Span操作后的部分数组: [{string.Join(", ", largeArray.Skip(100).Take(10))}]...");
// 避免装箱和拆箱
Console.WriteLine("\n3. 避免装箱和拆箱");
// 不好的做法:装箱
object[] objects = new object[5];
for (int i = 0; i < 5; i++)
{
objects[i] = i; // 装箱
}
// 好的做法:使用泛型
int[] integers = new int[5];
for (int i = 0; i < 5; i++)
{
integers[i] = i; // 无装箱
}
Console.WriteLine("使用泛型数组避免装箱,提高性能");
}
}
2. 集合类型
2.1 List - 动态数组
using System;
using System.Collections.Generic;
using System.Linq;
public class ListExamples
{
public static void Main()
{
Console.WriteLine("=== List<T> 示例 ===");
// 基本操作
DemonstrateBasicListOperations();
// 高级操作
DemonstrateAdvancedListOperations();
// 性能比较
CompareListPerformance();
}
private static void DemonstrateBasicListOperations()
{
Console.WriteLine("\n--- List基本操作 ---");
// 创建List
var numbers = new List<int>();
Console.WriteLine($"空List容量: {numbers.Capacity}, 元素数: {numbers.Count}");
// 添加元素
numbers.Add(10);
numbers.Add(20);
numbers.Add(30);
Console.WriteLine($"添加3个元素后: [{string.Join(", ", numbers)}]");
// 批量添加
numbers.AddRange(new[] { 40, 50, 60 });
Console.WriteLine($"批量添加后: [{string.Join(", ", numbers)}]");
// 插入元素
numbers.Insert(0, 5); // 在索引0处插入
numbers.Insert(3, 25); // 在索引3处插入
Console.WriteLine($"插入元素后: [{string.Join(", ", numbers)}]");
// 访问元素
Console.WriteLine($"第一个元素: {numbers[0]}");
Console.WriteLine($"最后一个元素: {numbers[numbers.Count - 1]}");
// 查找元素
int index = numbers.IndexOf(30);
Console.WriteLine($"数字30的索引: {index}");
bool contains = numbers.Contains(25);
Console.WriteLine($"是否包含25: {contains}");
// 删除元素
numbers.Remove(25); // 删除第一个匹配的元素
Console.WriteLine($"删除25后: [{string.Join(", ", numbers)}]");
numbers.RemoveAt(0); // 删除指定索引的元素
Console.WriteLine($"删除索引0后: [{string.Join(", ", numbers)}]");
// 修改元素
numbers[0] = 100;
Console.WriteLine($"修改第一个元素后: [{string.Join(", ", numbers)}]");
// 遍历
Console.WriteLine("\n使用foreach遍历:");
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
Console.WriteLine();
Console.WriteLine("\n使用for循环遍历:");
for (int i = 0; i < numbers.Count; i++)
{
Console.Write($"[{i}]={numbers[i]} ");
}
Console.WriteLine();
}
private static void DemonstrateAdvancedListOperations()
{
Console.WriteLine("\n--- List高级操作 ---");
var students = new List<Student>
{
new Student { Name = "Alice", Age = 20, Grade = 85 },
new Student { Name = "Bob", Age = 22, Grade = 92 },
new Student { Name = "Charlie", Age = 19, Grade = 78 },
new Student { Name = "David", Age = 21, Grade = 88 },
new Student { Name = "Eve", Age = 20, Grade = 95 }
};
Console.WriteLine("学生列表:");
students.ForEach(s => Console.WriteLine($"{s.Name}, {s.Age}岁, 成绩: {s.Grade}"));
// 查找操作
var topStudent = students.Find(s => s.Grade > 90);
Console.WriteLine($"\n第一个成绩>90的学生: {topStudent?.Name}");
var allTopStudents = students.FindAll(s => s.Grade > 85);
Console.WriteLine($"所有成绩>85的学生: {string.Join(", ", allTopStudents.Select(s => s.Name))}");
var youngStudent = students.FindLast(s => s.Age < 21);
Console.WriteLine($"最后一个年龄<21的学生: {youngStudent?.Name}");
// 条件检查
bool hasExcellent = students.Exists(s => s.Grade >= 95);
Console.WriteLine($"\n是否有优秀学生(≥95分): {hasExcellent}");
bool allPassed = students.TrueForAll(s => s.Grade >= 60);
Console.WriteLine($"是否所有学生都及格(≥60分): {allPassed}");
// 排序
students.Sort((s1, s2) => s1.Grade.CompareTo(s2.Grade));
Console.WriteLine("\n按成绩升序排列:");
students.ForEach(s => Console.WriteLine($"{s.Name}: {s.Grade}"));
students.Sort((s1, s2) => s2.Age.CompareTo(s1.Age));
Console.WriteLine("\n按年龄降序排列:");
students.ForEach(s => Console.WriteLine($"{s.Name}: {s.Age}岁"));
// 转换
var names = students.ConvertAll(s => s.Name.ToUpper());
Console.WriteLine($"\n学生姓名(大写): [{string.Join(", ", names)}]");
// 分页
int pageSize = 2;
var pages = students
.Select((student, index) => new { student, index })
.GroupBy(x => x.index / pageSize)
.Select(g => g.Select(x => x.student).ToList())
.ToList();
Console.WriteLine($"\n分页显示(每页{pageSize}个):");
for (int i = 0; i < pages.Count; i++)
{
Console.WriteLine($"第{i + 1}页: {string.Join(", ", pages[i].Select(s => s.Name))}");
}
// 去重
var ages = students.Select(s => s.Age).Distinct().OrderBy(age => age).ToList();
Console.WriteLine($"\n不同年龄: [{string.Join(", ", ages)}]");
// 分组
var ageGroups = students.GroupBy(s => s.Age)
.Select(g => new { Age = g.Key, Students = g.ToList() })
.ToList();
Console.WriteLine("\n按年龄分组:");
foreach (var group in ageGroups)
{
Console.WriteLine($"{group.Age}岁: {string.Join(", ", group.Students.Select(s => s.Name))}");
}
}
private static void CompareListPerformance()
{
Console.WriteLine("\n--- List性能比较 ---");
const int size = 100000;
// 测试添加性能
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
var list1 = new List<int>();
for (int i = 0; i < size; i++)
{
list1.Add(i);
}
stopwatch.Stop();
Console.WriteLine($"List添加{size}个元素耗时: {stopwatch.ElapsedMilliseconds}ms");
// 预分配容量的性能
stopwatch.Restart();
var list2 = new List<int>(size);
for (int i = 0; i < size; i++)
{
list2.Add(i);
}
stopwatch.Stop();
Console.WriteLine($"预分配容量的List添加{size}个元素耗时: {stopwatch.ElapsedMilliseconds}ms");
// 数组性能
stopwatch.Restart();
var array = new int[size];
for (int i = 0; i < size; i++)
{
array[i] = i;
}
stopwatch.Stop();
Console.WriteLine($"数组赋值{size}个元素耗时: {stopwatch.ElapsedMilliseconds}ms");
// 访问性能比较
Random random = new Random();
int sum = 0;
stopwatch.Restart();
for (int i = 0; i < 10000; i++)
{
int index = random.Next(size);
sum += list1[index];
}
stopwatch.Stop();
Console.WriteLine($"List随机访问10000次耗时: {stopwatch.ElapsedMilliseconds}ms");
sum = 0;
stopwatch.Restart();
for (int i = 0; i < 10000; i++)
{
int index = random.Next(size);
sum += array[index];
}
stopwatch.Stop();
Console.WriteLine($"数组随机访问10000次耗时: {stopwatch.ElapsedMilliseconds}ms");
}
public class Student
{
public string Name { get; set; } = "";
public int Age { get; set; }
public int Grade { get; set; }
}
}
2.2 Dictionary - 字典
using System;
using System.Collections.Generic;
using System.Linq;
public class DictionaryExamples
{
public static void Main()
{
Console.WriteLine("=== Dictionary<TKey, TValue> 示例 ===");
// 基本操作
DemonstrateBasicDictionaryOperations();
// 高级操作
DemonstrateAdvancedDictionaryOperations();
// 实际应用场景
DemonstratePracticalUseCases();
}
private static void DemonstrateBasicDictionaryOperations()
{
Console.WriteLine("\n--- Dictionary基本操作 ---");
// 创建Dictionary
var studentGrades = new Dictionary<string, int>();
// 添加键值对
studentGrades.Add("Alice", 85);
studentGrades.Add("Bob", 92);
studentGrades.Add("Charlie", 78);
Console.WriteLine($"字典元素数: {studentGrades.Count}");
// 使用索引器添加/修改
studentGrades["David"] = 88; // 添加新元素
studentGrades["Alice"] = 90; // 修改现有元素
Console.WriteLine("\n学生成绩:");
foreach (var kvp in studentGrades)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// 访问元素
Console.WriteLine($"\nAlice的成绩: {studentGrades["Alice"]}");
// 安全访问(避免KeyNotFoundException)
if (studentGrades.TryGetValue("Eve", out int eveGrade))
{
Console.WriteLine($"Eve的成绩: {eveGrade}");
}
else
{
Console.WriteLine("Eve不在字典中");
}
// 检查键是否存在
bool hasCharlie = studentGrades.ContainsKey("Charlie");
Console.WriteLine($"\n是否包含Charlie: {hasCharlie}");
// 检查值是否存在
bool hasGrade90 = studentGrades.ContainsValue(90);
Console.WriteLine($"是否有人得90分: {hasGrade90}");
// 删除元素
bool removed = studentGrades.Remove("Charlie");
Console.WriteLine($"\n删除Charlie: {removed}");
Console.WriteLine($"删除后元素数: {studentGrades.Count}");
// 获取所有键和值
var allNames = studentGrades.Keys.ToList();
var allGrades = studentGrades.Values.ToList();
Console.WriteLine($"\n所有学生: [{string.Join(", ", allNames)}]");
Console.WriteLine($"所有成绩: [{string.Join(", ", allGrades)}]");
// 清空字典
var copy = new Dictionary<string, int>(studentGrades);
copy.Clear();
Console.WriteLine($"\n清空后元素数: {copy.Count}");
}
private static void DemonstrateAdvancedDictionaryOperations()
{
Console.WriteLine("\n--- Dictionary高级操作 ---");
// 初始化字典的不同方式
var colors = new Dictionary<string, string>
{
{ "red", "红色" },
{ "green", "绿色" },
{ "blue", "蓝色" }
};
// C# 6.0+ 索引初始化器
var fruits = new Dictionary<string, double>
{
["apple"] = 3.5,
["banana"] = 2.8,
["orange"] = 4.2
};
Console.WriteLine("颜色字典:");
foreach (var color in colors)
{
Console.WriteLine($"{color.Key} -> {color.Value}");
}
Console.WriteLine("\n水果价格:");
foreach (var fruit in fruits)
{
Console.WriteLine($"{fruit.Key}: ${fruit.Value:F2}");
}
// 复杂值类型的字典
var employees = new Dictionary<int, Employee>
{
{ 1001, new Employee { Name = "Alice", Department = "IT", Salary = 75000 } },
{ 1002, new Employee { Name = "Bob", Department = "HR", Salary = 65000 } },
{ 1003, new Employee { Name = "Charlie", Department = "Finance", Salary = 80000 } }
};
Console.WriteLine("\n员工信息:");
foreach (var emp in employees)
{
Console.WriteLine($"ID {emp.Key}: {emp.Value.Name}, {emp.Value.Department}, ${emp.Value.Salary:N0}");
}
// 嵌套字典
var departmentEmployees = new Dictionary<string, Dictionary<int, string>>
{
{
"IT", new Dictionary<int, string>
{
{ 1001, "Alice" },
{ 1004, "David" }
}
},
{
"HR", new Dictionary<int, string>
{
{ 1002, "Bob" },
{ 1005, "Eve" }
}
}
};
Console.WriteLine("\n部门员工:");
foreach (var dept in departmentEmployees)
{
Console.WriteLine($"{dept.Key}部门:");
foreach (var emp in dept.Value)
{
Console.WriteLine($" ID {emp.Key}: {emp.Value}");
}
}
// 字典的LINQ操作
Console.WriteLine("\n--- 字典LINQ操作 ---");
// 过滤
var highSalaryEmployees = employees.Where(e => e.Value.Salary > 70000)
.ToDictionary(e => e.Key, e => e.Value);
Console.WriteLine("高薪员工(>70000):");
foreach (var emp in highSalaryEmployees)
{
Console.WriteLine($"ID {emp.Key}: {emp.Value.Name}, ${emp.Value.Salary:N0}");
}
// 分组
var employeesByDept = employees.Values
.GroupBy(e => e.Department)
.ToDictionary(g => g.Key, g => g.ToList());
Console.WriteLine("\n按部门分组:");
foreach (var dept in employeesByDept)
{
Console.WriteLine($"{dept.Key}: {string.Join(", ", dept.Value.Select(e => e.Name))}");
}
// 转换
var employeeNames = employees.ToDictionary(e => e.Key, e => e.Value.Name);
Console.WriteLine($"\n员工姓名映射: {string.Join(", ", employeeNames.Select(e => $"{e.Key}:{e.Value}"))}");
}
private static void DemonstratePracticalUseCases()
{
Console.WriteLine("\n--- 实际应用场景 ---");
// 1. 缓存系统
Console.WriteLine("1. 简单缓存系统:");
var cache = new Dictionary<string, CacheItem>();
// 添加缓存项
cache["user:1001"] = new CacheItem { Data = "Alice的用户数据", Timestamp = DateTime.Now };
cache["user:1002"] = new CacheItem { Data = "Bob的用户数据", Timestamp = DateTime.Now.AddMinutes(-5) };
// 获取缓存
string GetFromCache(string key)
{
if (cache.TryGetValue(key, out CacheItem item))
{
// 检查是否过期(5分钟)
if (DateTime.Now - item.Timestamp < TimeSpan.FromMinutes(5))
{
return item.Data;
}
else
{
cache.Remove(key); // 移除过期项
return null;
}
}
return null;
}
Console.WriteLine($"获取user:1001: {GetFromCache("user:1001") ?? "缓存未命中"}");
Console.WriteLine($"获取user:1002: {GetFromCache("user:1002") ?? "缓存已过期"}");
// 2. 计数器
Console.WriteLine("\n2. 字符计数器:");
string text = "hello world";
var charCount = new Dictionary<char, int>();
foreach (char c in text)
{
if (char.IsLetter(c))
{
charCount[c] = charCount.GetValueOrDefault(c, 0) + 1;
}
}
Console.WriteLine("字符出现次数:");
foreach (var count in charCount.OrderBy(c => c.Key))
{
Console.WriteLine($"'{count.Key}': {count.Value}次");
}
// 3. 配置管理
Console.WriteLine("\n3. 配置管理:");
var config = new Dictionary<string, object>
{
{ "database.host", "localhost" },
{ "database.port", 5432 },
{ "database.timeout", 30 },
{ "app.debug", true },
{ "app.version", "1.0.0" }
};
// 类型安全的配置获取
T GetConfig<T>(string key, T defaultValue = default(T))
{
if (config.TryGetValue(key, out object value) && value is T)
{
return (T)value;
}
return defaultValue;
}
Console.WriteLine($"数据库主机: {GetConfig<string>("database.host")}");
Console.WriteLine($"数据库端口: {GetConfig<int>("database.port")}");
Console.WriteLine($"调试模式: {GetConfig<bool>("app.debug")}");
Console.WriteLine($"不存在的配置: {GetConfig<string>("app.theme", "default")}");
// 4. 多语言支持
Console.WriteLine("\n4. 多语言支持:");
var translations = new Dictionary<string, Dictionary<string, string>>
{
{
"en", new Dictionary<string, string>
{
{ "hello", "Hello" },
{ "goodbye", "Goodbye" },
{ "thank_you", "Thank you" }
}
},
{
"zh", new Dictionary<string, string>
{
{ "hello", "你好" },
{ "goodbye", "再见" },
{ "thank_you", "谢谢" }
}
}
};
string Translate(string key, string language = "en")
{
if (translations.TryGetValue(language, out var langDict) &&
langDict.TryGetValue(key, out string translation))
{
return translation;
}
return key; // 返回原始key作为fallback
}
Console.WriteLine($"英文问候: {Translate("hello", "en")}");
Console.WriteLine($"中文问候: {Translate("hello", "zh")}");
Console.WriteLine($"英文感谢: {Translate("thank_you", "en")}");
Console.WriteLine($"中文感谢: {Translate("thank_you", "zh")}");
}
public class Employee
{
public string Name { get; set; } = "";
public string Department { get; set; } = "";
public decimal Salary { get; set; }
}
public class CacheItem
{
public string Data { get; set; } = "";
public DateTime Timestamp { get; set; }
}
}
2.3 其他重要集合类型
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
public class OtherCollectionTypes
{
public static void Main()
{
Console.WriteLine("=== 其他重要集合类型 ===");
// HashSet<T>
DemonstrateHashSet();
// Queue<T> 和 Stack<T>
DemonstrateQueueAndStack();
// SortedDictionary 和 SortedList
DemonstrateSortedCollections();
// 并发集合
DemonstrateConcurrentCollections();
// LinkedList<T>
DemonstrateLinkedList();
}
private static void DemonstrateHashSet()
{
Console.WriteLine("\n--- HashSet<T> ---");
// 创建HashSet
var numbers = new HashSet<int> { 1, 2, 3, 4, 5 };
Console.WriteLine($"初始集合: [{string.Join(", ", numbers)}]");
// 添加元素(重复元素会被忽略)
bool added1 = numbers.Add(6);
bool added2 = numbers.Add(3); // 重复元素
Console.WriteLine($"添加6: {added1}, 添加3: {added2}");
Console.WriteLine($"当前集合: [{string.Join(", ", numbers)}]");
// 集合操作
var otherNumbers = new HashSet<int> { 4, 5, 6, 7, 8 };
Console.WriteLine($"另一个集合: [{string.Join(", ", otherNumbers)}]");
// 并集
var union = new HashSet<int>(numbers);
union.UnionWith(otherNumbers);
Console.WriteLine($"并集: [{string.Join(", ", union.OrderBy(x => x))}]");
// 交集
var intersection = new HashSet<int>(numbers);
intersection.IntersectWith(otherNumbers);
Console.WriteLine($"交集: [{string.Join(", ", intersection.OrderBy(x => x))}]");
// 差集
var except = new HashSet<int>(numbers);
except.ExceptWith(otherNumbers);
Console.WriteLine($"差集(numbers - otherNumbers): [{string.Join(", ", except.OrderBy(x => x))}]");
// 对称差集
var symmetricExcept = new HashSet<int>(numbers);
symmetricExcept.SymmetricExceptWith(otherNumbers);
Console.WriteLine($"对称差集: [{string.Join(", ", symmetricExcept.OrderBy(x => x))}]");
// 子集检查
var subset = new HashSet<int> { 1, 2, 3 };
bool isSubset = subset.IsSubsetOf(numbers);
bool isSuperset = numbers.IsSupersetOf(subset);
Console.WriteLine($"\n{{{string.Join(", ", subset)}}} 是 {{{string.Join(", ", numbers)}}} 的子集: {isSubset}");
Console.WriteLine($"{{{string.Join(", ", numbers)}}} 是 {{{string.Join(", ", subset)}}} 的超集: {isSuperset}");
// 去重应用
Console.WriteLine("\n--- 去重应用 ---");
var duplicateNumbers = new List<int> { 1, 2, 2, 3, 3, 3, 4, 4, 5 };
var uniqueNumbers = new HashSet<int>(duplicateNumbers);
Console.WriteLine($"原始列表: [{string.Join(", ", duplicateNumbers)}]");
Console.WriteLine($"去重后: [{string.Join(", ", uniqueNumbers.OrderBy(x => x))}]");
}
private static void DemonstrateQueueAndStack()
{
Console.WriteLine("\n--- Queue<T> 和 Stack<T> ---");
// Queue (先进先出 FIFO)
Console.WriteLine("\nQueue (先进先出):");
var queue = new Queue<string>();
// 入队
queue.Enqueue("第一个");
queue.Enqueue("第二个");
queue.Enqueue("第三个");
Console.WriteLine($"队列元素数: {queue.Count}");
Console.WriteLine($"队列内容: [{string.Join(", ", queue)}]");
// 查看队首元素(不移除)
string front = queue.Peek();
Console.WriteLine($"队首元素: {front}");
// 出队
while (queue.Count > 0)
{
string item = queue.Dequeue();
Console.WriteLine($"出队: {item}, 剩余: {queue.Count}");
}
// Stack (后进先出 LIFO)
Console.WriteLine("\nStack (后进先出):");
var stack = new Stack<string>();
// 入栈
stack.Push("底部");
stack.Push("中间");
stack.Push("顶部");
Console.WriteLine($"栈元素数: {stack.Count}");
Console.WriteLine($"栈内容: [{string.Join(", ", stack)}]");
// 查看栈顶元素(不移除)
string top = stack.Peek();
Console.WriteLine($"栈顶元素: {top}");
// 出栈
while (stack.Count > 0)
{
string item = stack.Pop();
Console.WriteLine($"出栈: {item}, 剩余: {stack.Count}");
}
// 实际应用:表达式求值
Console.WriteLine("\n--- 实际应用:括号匹配检查 ---");
string[] expressions = {
"((()))",
"(()())",
"((())",
")(()",
"({[]})"
};
foreach (string expr in expressions)
{
bool isValid = IsValidParentheses(expr);
Console.WriteLine($"{expr}: {(isValid ? "有效" : "无效")}");
}
}
private static bool IsValidParentheses(string s)
{
var stack = new Stack<char>();
var pairs = new Dictionary<char, char>
{
{ ')', '(' },
{ '}', '{' },
{ ']', '[' }
};
foreach (char c in s)
{
if (c == '(' || c == '{' || c == '[')
{
stack.Push(c);
}
else if (c == ')' || c == '}' || c == ']')
{
if (stack.Count == 0 || stack.Pop() != pairs[c])
{
return false;
}
}
}
return stack.Count == 0;
}
private static void DemonstrateSortedCollections()
{
Console.WriteLine("\n--- SortedDictionary 和 SortedList ---");
// SortedDictionary - 基于红黑树,插入和查找都是O(log n)
Console.WriteLine("\nSortedDictionary:");
var sortedDict = new SortedDictionary<string, int>();
sortedDict["banana"] = 2;
sortedDict["apple"] = 1;
sortedDict["cherry"] = 3;
sortedDict["date"] = 4;
Console.WriteLine("自动按键排序:");
foreach (var kvp in sortedDict)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// SortedList - 基于数组,查找O(log n),插入O(n)
Console.WriteLine("\nSortedList:");
var sortedList = new SortedList<int, string>();
sortedList[30] = "三十";
sortedList[10] = "十";
sortedList[20] = "二十";
sortedList[40] = "四十";
Console.WriteLine("自动按键排序:");
foreach (var kvp in sortedList)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// 按索引访问(SortedList特有)
Console.WriteLine($"\n索引0的键值对: {sortedList.Keys[0]} -> {sortedList.Values[0]}");
Console.WriteLine($"索引1的键值对: {sortedList.Keys[1]} -> {sortedList.Values[1]}");
// 自定义比较器
Console.WriteLine("\n--- 自定义比较器 ---");
var customSorted = new SortedDictionary<string, int>(StringComparer.OrdinalIgnoreCase);
customSorted["Apple"] = 1;
customSorted["apple"] = 2; // 会覆盖上面的值,因为忽略大小写
customSorted["BANANA"] = 3;
customSorted["banana"] = 4; // 会覆盖上面的值
Console.WriteLine("忽略大小写的排序:");
foreach (var kvp in customSorted)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
}
private static void DemonstrateConcurrentCollections()
{
Console.WriteLine("\n--- 并发集合 ---");
// ConcurrentDictionary - 线程安全的字典
Console.WriteLine("\nConcurrentDictionary:");
var concurrentDict = new ConcurrentDictionary<string, int>();
// 并发添加
Parallel.For(0, 10, i =>
{
string key = $"key{i}";
concurrentDict.TryAdd(key, i * 10);
});
Console.WriteLine("并发添加的结果:");
foreach (var kvp in concurrentDict.OrderBy(x => x.Key))
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// 原子操作
concurrentDict.AddOrUpdate("counter", 1, (key, oldValue) => oldValue + 1);
concurrentDict.AddOrUpdate("counter", 1, (key, oldValue) => oldValue + 1);
Console.WriteLine($"\n计数器值: {concurrentDict["counter"]}");
// ConcurrentQueue - 线程安全的队列
Console.WriteLine("\nConcurrentQueue:");
var concurrentQueue = new ConcurrentQueue<string>();
// 并发入队
Parallel.For(0, 5, i =>
{
concurrentQueue.Enqueue($"Item{i}");
});
Console.WriteLine($"队列元素数: {concurrentQueue.Count}");
// 并发出队
while (concurrentQueue.TryDequeue(out string item))
{
Console.WriteLine($"出队: {item}");
}
// ConcurrentBag - 线程安全的无序集合
Console.WriteLine("\nConcurrentBag:");
var concurrentBag = new ConcurrentBag<int>();
Parallel.For(0, 10, i =>
{
concurrentBag.Add(i);
});
Console.WriteLine($"Bag元素: [{string.Join(", ", concurrentBag.OrderBy(x => x))}]");
}
private static void DemonstrateLinkedList()
{
Console.WriteLine("\n--- LinkedList<T> ---");
var linkedList = new LinkedList<string>();
// 添加元素
var firstNode = linkedList.AddFirst("第一个");
var lastNode = linkedList.AddLast("最后一个");
var middleNode = linkedList.AddAfter(firstNode, "中间");
Console.WriteLine($"链表内容: [{string.Join(" -> ", linkedList)}]");
// 在特定位置插入
linkedList.AddBefore(middleNode, "中间前");
linkedList.AddAfter(middleNode, "中间后");
Console.WriteLine($"插入后: [{string.Join(" -> ", linkedList)}]");
// 遍历链表
Console.WriteLine("\n正向遍历:");
var current = linkedList.First;
while (current != null)
{
Console.WriteLine($"节点值: {current.Value}");
current = current.Next;
}
Console.WriteLine("\n反向遍历:");
current = linkedList.Last;
while (current != null)
{
Console.WriteLine($"节点值: {current.Value}");
current = current.Previous;
}
// 删除节点
linkedList.Remove(middleNode);
linkedList.RemoveFirst();
linkedList.RemoveLast();
Console.WriteLine($"\n删除后: [{string.Join(" -> ", linkedList)}]");
// LinkedList vs List 性能比较
Console.WriteLine("\n--- LinkedList vs List 性能比较 ---");
const int size = 10000;
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// LinkedList 插入性能
var ll = new LinkedList<int>();
for (int i = 0; i < size; i++)
{
ll.AddLast(i);
}
stopwatch.Stop();
Console.WriteLine($"LinkedList添加{size}个元素: {stopwatch.ElapsedMilliseconds}ms");
// List 插入性能
stopwatch.Restart();
var list = new List<int>();
for (int i = 0; i < size; i++)
{
list.Add(i);
}
stopwatch.Stop();
Console.WriteLine($"List添加{size}个元素: {stopwatch.ElapsedMilliseconds}ms");
// 中间插入性能
stopwatch.Restart();
var node = ll.First;
for (int i = 0; i < ll.Count / 2; i++)
{
node = node.Next;
}
ll.AddAfter(node, 99999);
stopwatch.Stop();
Console.WriteLine($"LinkedList中间插入: {stopwatch.ElapsedTicks} ticks");
stopwatch.Restart();
list.Insert(list.Count / 2, 99999);
stopwatch.Stop();
Console.WriteLine($"List中间插入: {stopwatch.ElapsedTicks} ticks");
}
}
3. 实践练习
3.1 学生管理系统
using System;
using System.Collections.Generic;
using System.Linq;
public class StudentManagementSystem
{
private List<Student> students;
private Dictionary<string, List<Course>> studentCourses;
private Dictionary<string, Dictionary<string, double>> grades;
public StudentManagementSystem()
{
students = new List<Student>();
studentCourses = new Dictionary<string, List<Course>>();
grades = new Dictionary<string, Dictionary<string, double>>();
}
public static void Main()
{
var system = new StudentManagementSystem();
system.RunDemo();
}
private void RunDemo()
{
Console.WriteLine("=== 学生管理系统 ===");
// 添加学生
AddStudent(new Student { Id = "S001", Name = "张三", Age = 20, Major = "计算机科学" });
AddStudent(new Student { Id = "S002", Name = "李四", Age = 21, Major = "软件工程" });
AddStudent(new Student { Id = "S003", Name = "王五", Age = 19, Major = "计算机科学" });
// 添加课程
var courses = new List<Course>
{
new Course { Code = "CS101", Name = "程序设计基础", Credits = 3 },
new Course { Code = "CS102", Name = "数据结构", Credits = 4 },
new Course { Code = "CS103", Name = "算法分析", Credits = 3 },
new Course { Code = "MATH101", Name = "高等数学", Credits = 4 }
};
// 为学生注册课程
RegisterStudentForCourse("S001", courses[0]);
RegisterStudentForCourse("S001", courses[1]);
RegisterStudentForCourse("S001", courses[3]);
RegisterStudentForCourse("S002", courses[0]);
RegisterStudentForCourse("S002", courses[2]);
RegisterStudentForCourse("S003", courses[1]);
RegisterStudentForCourse("S003", courses[2]);
RegisterStudentForCourse("S003", courses[3]);
// 录入成绩
RecordGrade("S001", "CS101", 85.5);
RecordGrade("S001", "CS102", 92.0);
RecordGrade("S001", "MATH101", 78.5);
RecordGrade("S002", "CS101", 88.0);
RecordGrade("S002", "CS103", 95.5);
RecordGrade("S003", "CS102", 91.0);
RecordGrade("S003", "CS103", 87.5);
RecordGrade("S003", "MATH101", 82.0);
// 显示系统信息
DisplayAllStudents();
DisplayStudentCourses();
DisplayGrades();
DisplayStatistics();
// 查询功能
Console.WriteLine("\n=== 查询功能 ===");
SearchStudentsByMajor("计算机科学");
FindTopStudents(2);
GetCourseStatistics("CS102");
}
public void AddStudent(Student student)
{
if (students.Any(s => s.Id == student.Id))
{
Console.WriteLine($"学生ID {student.Id} 已存在");
return;
}
students.Add(student);
studentCourses[student.Id] = new List<Course>();
grades[student.Id] = new Dictionary<string, double>();
Console.WriteLine($"添加学生: {student.Name} (ID: {student.Id})");
}
public void RegisterStudentForCourse(string studentId, Course course)
{
if (!studentCourses.ContainsKey(studentId))
{
Console.WriteLine($"学生ID {studentId} 不存在");
return;
}
if (studentCourses[studentId].Any(c => c.Code == course.Code))
{
Console.WriteLine($"学生 {studentId} 已注册课程 {course.Code}");
return;
}
studentCourses[studentId].Add(course);
Console.WriteLine($"学生 {studentId} 注册课程: {course.Name} ({course.Code})");
}
public void RecordGrade(string studentId, string courseCode, double grade)
{
if (!grades.ContainsKey(studentId))
{
Console.WriteLine($"学生ID {studentId} 不存在");
return;
}
if (!studentCourses[studentId].Any(c => c.Code == courseCode))
{
Console.WriteLine($"学生 {studentId} 未注册课程 {courseCode}");
return;
}
grades[studentId][courseCode] = grade;
Console.WriteLine($"录入成绩: 学生 {studentId}, 课程 {courseCode}, 成绩 {grade}");
}
public void DisplayAllStudents()
{
Console.WriteLine("\n=== 所有学生信息 ===");
foreach (var student in students.OrderBy(s => s.Id))
{
Console.WriteLine($"ID: {student.Id}, 姓名: {student.Name}, 年龄: {student.Age}, 专业: {student.Major}");
}
}
public void DisplayStudentCourses()
{
Console.WriteLine("\n=== 学生课程信息 ===");
foreach (var kvp in studentCourses)
{
var student = students.First(s => s.Id == kvp.Key);
Console.WriteLine($"\n{student.Name} ({kvp.Key}) 的课程:");
if (kvp.Value.Count == 0)
{
Console.WriteLine(" 未注册任何课程");
}
else
{
foreach (var course in kvp.Value.OrderBy(c => c.Code))
{
Console.WriteLine($" {course.Code}: {course.Name} ({course.Credits}学分)");
}
}
}
}
public void DisplayGrades()
{
Console.WriteLine("\n=== 学生成绩信息 ===");
foreach (var studentGrades in grades)
{
var student = students.First(s => s.Id == studentGrades.Key);
Console.WriteLine($"\n{student.Name} ({studentGrades.Key}) 的成绩:");
if (studentGrades.Value.Count == 0)
{
Console.WriteLine(" 暂无成绩记录");
}
else
{
double totalGrade = 0;
int totalCredits = 0;
foreach (var grade in studentGrades.Value.OrderBy(g => g.Key))
{
var course = studentCourses[studentGrades.Key].First(c => c.Code == grade.Key);
Console.WriteLine($" {grade.Key}: {grade.Value:F1}分");
totalGrade += grade.Value * course.Credits;
totalCredits += course.Credits;
}
if (totalCredits > 0)
{
double gpa = totalGrade / totalCredits;
Console.WriteLine($" 加权平均分: {gpa:F2}");
}
}
}
}
public void DisplayStatistics()
{
Console.WriteLine("\n=== 统计信息 ===");
// 专业统计
var majorStats = students.GroupBy(s => s.Major)
.Select(g => new { Major = g.Key, Count = g.Count() })
.OrderByDescending(x => x.Count);
Console.WriteLine("\n专业分布:");
foreach (var stat in majorStats)
{
Console.WriteLine($" {stat.Major}: {stat.Count}人");
}
// 年龄统计
if (students.Count > 0)
{
double avgAge = students.Average(s => s.Age);
int minAge = students.Min(s => s.Age);
int maxAge = students.Max(s => s.Age);
Console.WriteLine($"\n年龄统计:");
Console.WriteLine($" 平均年龄: {avgAge:F1}岁");
Console.WriteLine($" 最小年龄: {minAge}岁");
Console.WriteLine($" 最大年龄: {maxAge}岁");
}
// 课程注册统计
var courseStats = studentCourses.SelectMany(sc => sc.Value)
.GroupBy(c => c.Code)
.Select(g => new {
Course = g.First(),
StudentCount = g.Count()
})
.OrderByDescending(x => x.StudentCount);
Console.WriteLine($"\n课程注册统计:");
foreach (var stat in courseStats)
{
Console.WriteLine($" {stat.Course.Code} ({stat.Course.Name}): {stat.StudentCount}人注册");
}
}
public void SearchStudentsByMajor(string major)
{
Console.WriteLine($"\n查找专业为 '{major}' 的学生:");
var studentsInMajor = students.Where(s => s.Major.Equals(major, StringComparison.OrdinalIgnoreCase))
.OrderBy(s => s.Name);
if (!studentsInMajor.Any())
{
Console.WriteLine(" 未找到符合条件的学生");
}
else
{
foreach (var student in studentsInMajor)
{
Console.WriteLine($" {student.Name} (ID: {student.Id}, 年龄: {student.Age})");
}
}
}
public void FindTopStudents(int count)
{
Console.WriteLine($"\n查找成绩前 {count} 名的学生:");
var studentGPAs = new List<(Student student, double gpa)>();
foreach (var student in students)
{
if (grades[student.Id].Count > 0)
{
double totalGrade = 0;
int totalCredits = 0;
foreach (var grade in grades[student.Id])
{
var course = studentCourses[student.Id].First(c => c.Code == grade.Key);
totalGrade += grade.Value * course.Credits;
totalCredits += course.Credits;
}
if (totalCredits > 0)
{
double gpa = totalGrade / totalCredits;
studentGPAs.Add((student, gpa));
}
}
}
var topStudents = studentGPAs.OrderByDescending(x => x.gpa)
.Take(count);
int rank = 1;
foreach (var (student, gpa) in topStudents)
{
Console.WriteLine($" 第{rank}名: {student.Name} (GPA: {gpa:F2})");
rank++;
}
}
public void GetCourseStatistics(string courseCode)
{
Console.WriteLine($"\n课程 {courseCode} 的统计信息:");
var courseGrades = grades.Where(sg => sg.Value.ContainsKey(courseCode))
.Select(sg => sg.Value[courseCode])
.ToList();
if (courseGrades.Count == 0)
{
Console.WriteLine(" 暂无成绩记录");
return;
}
double average = courseGrades.Average();
double min = courseGrades.Min();
double max = courseGrades.Max();
int passCount = courseGrades.Count(g => g >= 60);
double passRate = (double)passCount / courseGrades.Count * 100;
Console.WriteLine($" 选课人数: {courseGrades.Count}");
Console.WriteLine($" 平均分: {average:F2}");
Console.WriteLine($" 最高分: {max:F1}");
Console.WriteLine($" 最低分: {min:F1}");
Console.WriteLine($" 及格人数: {passCount}");
Console.WriteLine($" 及格率: {passRate:F1}%");
// 成绩分布
var gradeRanges = new Dictionary<string, int>
{
{ "优秀(90-100)", courseGrades.Count(g => g >= 90) },
{ "良好(80-89)", courseGrades.Count(g => g >= 80 && g < 90) },
{ "中等(70-79)", courseGrades.Count(g => g >= 70 && g < 80) },
{ "及格(60-69)", courseGrades.Count(g => g >= 60 && g < 70) },
{ "不及格(<60)", courseGrades.Count(g => g < 60) }
};
Console.WriteLine(" 成绩分布:");
foreach (var range in gradeRanges)
{
if (range.Value > 0)
{
double percentage = (double)range.Value / courseGrades.Count * 100;
Console.WriteLine($" {range.Key}: {range.Value}人 ({percentage:F1}%)");
}
}
}
public class Student
{
public string Id { get; set; } = "";
public string Name { get; set; } = "";
public int Age { get; set; }
public string Major { get; set; } = "";
}
public class Course
{
public string Code { get; set; } = "";
public string Name { get; set; } = "";
public int Credits { get; set; }
}
}
3.2 数据分析工具
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
public class DataAnalysisTool
{
public static void Main()
{
Console.WriteLine("=== 数据分析工具 ===");
// 模拟销售数据
var salesData = GenerateSampleSalesData();
var analyzer = new DataAnalyzer();
// 基础统计分析
analyzer.BasicStatistics(salesData);
// 时间序列分析
analyzer.TimeSeriesAnalysis(salesData);
// 产品分析
analyzer.ProductAnalysis(salesData);
// 地区分析
analyzer.RegionAnalysis(salesData);
// 趋势分析
analyzer.TrendAnalysis(salesData);
}
private static List<SalesRecord> GenerateSampleSalesData()
{
var random = new Random(42); // 固定种子以获得可重复的结果
var products = new[] { "笔记本电脑", "台式机", "平板电脑", "手机", "耳机", "键盘", "鼠标" };
var regions = new[] { "北京", "上海", "广州", "深圳", "杭州", "成都", "武汉" };
var salespeople = new[] { "张三", "李四", "王五", "赵六", "钱七", "孙八", "周九" };
var salesData = new List<SalesRecord>();
var startDate = new DateTime(2023, 1, 1);
for (int i = 0; i < 1000; i++)
{
var record = new SalesRecord
{
Id = i + 1,
Date = startDate.AddDays(random.Next(365)),
Product = products[random.Next(products.Length)],
Region = regions[random.Next(regions.Length)],
Salesperson = salespeople[random.Next(salespeople.Length)],
Quantity = random.Next(1, 21),
UnitPrice = random.Next(100, 5001),
CustomerType = random.NextDouble() > 0.3 ? "企业" : "个人"
};
record.TotalAmount = record.Quantity * record.UnitPrice;
salesData.Add(record);
}
return salesData.OrderBy(s => s.Date).ToList();
}
}
public class DataAnalyzer
{
public void BasicStatistics(List<SalesRecord> data)
{
Console.WriteLine("\n=== 基础统计分析 ===");
if (!data.Any())
{
Console.WriteLine("无数据可分析");
return;
}
// 总体统计
var totalRecords = data.Count;
var totalRevenue = data.Sum(s => s.TotalAmount);
var totalQuantity = data.Sum(s => s.Quantity);
var avgOrderValue = data.Average(s => s.TotalAmount);
var avgQuantity = data.Average(s => s.Quantity);
Console.WriteLine($"总记录数: {totalRecords:N0}");
Console.WriteLine($"总收入: ¥{totalRevenue:N2}");
Console.WriteLine($"总销量: {totalQuantity:N0}");
Console.WriteLine($"平均订单金额: ¥{avgOrderValue:N2}");
Console.WriteLine($"平均订单数量: {avgQuantity:F2}");
// 收入分布统计
var revenueRanges = new Dictionary<string, int>
{
{ "<1000", data.Count(s => s.TotalAmount < 1000) },
{ "1000-5000", data.Count(s => s.TotalAmount >= 1000 && s.TotalAmount < 5000) },
{ "5000-10000", data.Count(s => s.TotalAmount >= 5000 && s.TotalAmount < 10000) },
{ "10000-50000", data.Count(s => s.TotalAmount >= 10000 && s.TotalAmount < 50000) },
{ ">=50000", data.Count(s => s.TotalAmount >= 50000) }
};
Console.WriteLine("\n订单金额分布:");
foreach (var range in revenueRanges)
{
double percentage = (double)range.Value / totalRecords * 100;
Console.WriteLine($" {range.Key}: {range.Value}笔 ({percentage:F1}%)");
}
// 客户类型分析
var customerTypeStats = data.GroupBy(s => s.CustomerType)
.Select(g => new {
Type = g.Key,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount),
AvgOrder = g.Average(s => s.TotalAmount)
})
.OrderByDescending(x => x.Revenue);
Console.WriteLine("\n客户类型分析:");
foreach (var stat in customerTypeStats)
{
double percentage = (double)stat.Count / totalRecords * 100;
Console.WriteLine($" {stat.Type}: {stat.Count}笔 ({percentage:F1}%), 收入: ¥{stat.Revenue:N2}, 平均: ¥{stat.AvgOrder:N2}");
}
}
public void TimeSeriesAnalysis(List<SalesRecord> data)
{
Console.WriteLine("\n=== 时间序列分析 ===");
// 按月统计
var monthlyStats = data.GroupBy(s => new { s.Date.Year, s.Date.Month })
.Select(g => new {
Year = g.Key.Year,
Month = g.Key.Month,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount),
Quantity = g.Sum(s => s.Quantity)
})
.OrderBy(x => x.Year).ThenBy(x => x.Month)
.ToList();
Console.WriteLine("月度销售统计:");
Console.WriteLine("年月\t\t订单数\t收入\t\t销量");
Console.WriteLine(new string('-', 60));
foreach (var stat in monthlyStats)
{
Console.WriteLine($"{stat.Year}-{stat.Month:D2}\t\t{stat.Count}\t¥{stat.Revenue:N0}\t\t{stat.Quantity}");
}
// 计算月度增长率
if (monthlyStats.Count > 1)
{
Console.WriteLine("\n月度收入增长率:");
for (int i = 1; i < monthlyStats.Count; i++)
{
var current = monthlyStats[i];
var previous = monthlyStats[i - 1];
double growthRate = (double)(current.Revenue - previous.Revenue) / previous.Revenue * 100;
Console.WriteLine($"{current.Year}-{current.Month:D2}: {growthRate:+0.0;-0.0;0.0}%");
}
}
// 按星期几统计
var weekdayStats = data.GroupBy(s => s.Date.DayOfWeek)
.Select(g => new {
DayOfWeek = g.Key,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount)
})
.OrderBy(x => (int)x.DayOfWeek)
.ToList();
Console.WriteLine("\n星期销售分布:");
foreach (var stat in weekdayStats)
{
double percentage = (double)stat.Count / data.Count * 100;
Console.WriteLine($"{GetDayOfWeekName(stat.DayOfWeek)}: {stat.Count}笔 ({percentage:F1}%), ¥{stat.Revenue:N2}");
}
}
public void ProductAnalysis(List<SalesRecord> data)
{
Console.WriteLine("\n=== 产品分析 ===");
var productStats = data.GroupBy(s => s.Product)
.Select(g => new {
Product = g.Key,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount),
Quantity = g.Sum(s => s.Quantity),
AvgPrice = g.Average(s => s.UnitPrice),
AvgQuantity = g.Average(s => s.Quantity)
})
.OrderByDescending(x => x.Revenue)
.ToList();
Console.WriteLine("产品销售排行:");
Console.WriteLine("排名\t产品\t\t订单数\t收入\t\t销量\t平均单价\t平均数量");
Console.WriteLine(new string('-', 80));
int rank = 1;
foreach (var stat in productStats)
{
Console.WriteLine($"{rank}\t{stat.Product}\t\t{stat.Count}\t¥{stat.Revenue:N0}\t\t{stat.Quantity}\t¥{stat.AvgPrice:F0}\t\t{stat.AvgQuantity:F1}");
rank++;
}
// 产品收入占比
var totalRevenue = productStats.Sum(p => p.Revenue);
Console.WriteLine("\n产品收入占比:");
foreach (var stat in productStats)
{
double percentage = (double)stat.Revenue / totalRevenue * 100;
Console.WriteLine($"{stat.Product}: {percentage:F1}%");
}
// 找出最受欢迎的产品组合
Console.WriteLine("\n=== 产品组合分析 ===");
var customerOrders = data.GroupBy(s => new { s.Date, s.Region, s.Salesperson })
.Where(g => g.Count() > 1) // 只考虑多产品订单
.Select(g => g.Select(s => s.Product).OrderBy(p => p).ToList())
.ToList();
var productCombinations = new Dictionary<string, int>();
foreach (var order in customerOrders)
{
for (int i = 0; i < order.Count - 1; i++)
{
for (int j = i + 1; j < order.Count; j++)
{
string combination = $"{order[i]} + {order[j]}";
productCombinations[combination] = productCombinations.GetValueOrDefault(combination, 0) + 1;
}
}
}
var topCombinations = productCombinations.OrderByDescending(c => c.Value)
.Take(5)
.ToList();
Console.WriteLine("热门产品组合 (Top 5):");
foreach (var combo in topCombinations)
{
Console.WriteLine($"{combo.Key}: {combo.Value}次");
}
}
public void RegionAnalysis(List<SalesRecord> data)
{
Console.WriteLine("\n=== 地区分析 ===");
var regionStats = data.GroupBy(s => s.Region)
.Select(g => new {
Region = g.Key,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount),
Quantity = g.Sum(s => s.Quantity),
AvgOrder = g.Average(s => s.TotalAmount),
UniqueCustomers = g.Select(s => s.Salesperson).Distinct().Count()
})
.OrderByDescending(x => x.Revenue)
.ToList();
Console.WriteLine("地区销售排行:");
Console.WriteLine("排名\t地区\t订单数\t收入\t\t销量\t平均订单\t销售人员");
Console.WriteLine(new string('-', 70));
int rank = 1;
foreach (var stat in regionStats)
{
Console.WriteLine($"{rank}\t{stat.Region}\t{stat.Count}\t¥{stat.Revenue:N0}\t\t{stat.Quantity}\t¥{stat.AvgOrder:N0}\t\t{stat.UniqueCustomers}");
rank++;
}
// 地区市场份额
var totalRevenue = regionStats.Sum(r => r.Revenue);
Console.WriteLine("\n地区市场份额:");
foreach (var stat in regionStats)
{
double percentage = (double)stat.Revenue / totalRevenue * 100;
string bar = new string('█', (int)(percentage / 2)); // 简单的条形图
Console.WriteLine($"{stat.Region}: {percentage:F1}% {bar}");
}
// 地区产品偏好
Console.WriteLine("\n=== 地区产品偏好 ===");
foreach (var region in regionStats.Take(3)) // 只显示前3个地区
{
Console.WriteLine($"\n{region.Region}地区热门产品:");
var regionProducts = data.Where(s => s.Region == region.Region)
.GroupBy(s => s.Product)
.Select(g => new {
Product = g.Key,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount)
})
.OrderByDescending(x => x.Revenue)
.Take(3)
.ToList();
foreach (var product in regionProducts)
{
Console.WriteLine($" {product.Product}: {product.Count}笔, ¥{product.Revenue:N0}");
}
}
}
public void TrendAnalysis(List<SalesRecord> data)
{
Console.WriteLine("\n=== 趋势分析 ===");
// 销售人员绩效分析
var salespersonStats = data.GroupBy(s => s.Salesperson)
.Select(g => new {
Salesperson = g.Key,
Count = g.Count(),
Revenue = g.Sum(s => s.TotalAmount),
AvgOrder = g.Average(s => s.TotalAmount),
Regions = g.Select(s => s.Region).Distinct().Count(),
Products = g.Select(s => s.Product).Distinct().Count()
})
.OrderByDescending(x => x.Revenue)
.ToList();
Console.WriteLine("销售人员绩效排行:");
Console.WriteLine("排名\t姓名\t订单数\t收入\t\t平均订单\t覆盖地区\t销售产品");
Console.WriteLine(new string('-', 75));
int rank = 1;
foreach (var stat in salespersonStats)
{
Console.WriteLine($"{rank}\t{stat.Salesperson}\t{stat.Count}\t¥{stat.Revenue:N0}\t\t¥{stat.AvgOrder:N0}\t\t{stat.Regions}\t\t{stat.Products}");
rank++;
}
// 计算销售效率指标
Console.WriteLine("\n=== 效率指标 ===");
var totalDays = (data.Max(s => s.Date) - data.Min(s => s.Date)).Days + 1;
var dailyAvgRevenue = data.Sum(s => s.TotalAmount) / totalDays;
var dailyAvgOrders = (double)data.Count / totalDays;
Console.WriteLine($"分析期间: {data.Min(s => s.Date):yyyy-MM-dd} 至 {data.Max(s => s.Date):yyyy-MM-dd} ({totalDays}天)");
Console.WriteLine($"日均收入: ¥{dailyAvgRevenue:N2}");
Console.WriteLine($"日均订单: {dailyAvgOrders:F1}笔");
// 预测下个月的销售额(简单线性趋势)
var monthlyRevenues = data.GroupBy(s => new { s.Date.Year, s.Date.Month })
.Select(g => g.Sum(s => s.TotalAmount))
.ToList();
if (monthlyRevenues.Count >= 3)
{
var recentTrend = monthlyRevenues.TakeLast(3).ToList();
var avgGrowth = 0.0;
for (int i = 1; i < recentTrend.Count; i++)
{
avgGrowth += (double)(recentTrend[i] - recentTrend[i - 1]) / recentTrend[i - 1];
}
avgGrowth /= (recentTrend.Count - 1);
var lastMonthRevenue = recentTrend.Last();
var predictedRevenue = lastMonthRevenue * (1 + avgGrowth);
Console.WriteLine($"\n基于近期趋势的下月预测收入: ¥{predictedRevenue:N2} (增长率: {avgGrowth:+0.0%;-0.0%;0.0%})");
}
}
private string GetDayOfWeekName(DayOfWeek dayOfWeek)
{
return dayOfWeek switch
{
DayOfWeek.Monday => "周一",
DayOfWeek.Tuesday => "周二",
DayOfWeek.Wednesday => "周三",
DayOfWeek.Thursday => "周四",
DayOfWeek.Friday => "周五",
DayOfWeek.Saturday => "周六",
DayOfWeek.Sunday => "周日",
_ => dayOfWeek.ToString()
};
}
}
public class SalesRecord
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string Product { get; set; } = "";
public string Region { get; set; } = "";
public string Salesperson { get; set; } = "";
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalAmount { get; set; }
public string CustomerType { get; set; } = "";
}
4. 集合选择指南
4.1 性能特性对比
集合类型 | 查找 | 插入 | 删除 | 内存使用 | 线程安全 | 适用场景 |
---|---|---|---|---|---|---|
Array | O(n) | N/A | N/A | 最优 | 否 | 固定大小,频繁随机访问 |
List |
O(n) | O(1)* | O(n) | 良好 | 否 | 动态大小,顺序访问 |
Dictionary |
O(1) | O(1) | O(1) | 中等 | 否 | 键值对存储,快速查找 |
HashSet |
O(1) | O(1) | O(1) | 中等 | 否 | 唯一元素集合,集合运算 |
Queue |
O(1) | O(1) | O(1) | 良好 | 否 | 先进先出处理 |
Stack |
O(1) | O(1) | O(1) | 良好 | 否 | 后进先出处理 |
LinkedList |
O(n) | O(1) | O(1) | 较高 | 否 | 频繁插入删除 |
SortedDictionary |
O(log n) | O(log n) | O(log n) | 中等 | 否 | 有序键值对 |
ConcurrentDictionary |
O(1) | O(1) | O(1) | 较高 | 是 | 多线程键值对存储 |
*注:List
4.2 选择建议
选择Array当: - 元素数量固定且已知 - 需要最佳的内存效率 - 频繁进行随机访问 - 与底层API交互
选择List
选择Dictionary
选择HashSet
选择Queue
选择Stack
选择LinkedList
5. 最佳实践
5.1 性能优化
- 预分配容量
“`csharp
// 好的做法
var list = new List
(1000); var dict = new Dictionary (1000);
// 避免频繁扩容
2. **选择合适的集合类型**
```csharp
// 需要唯一性检查时使用HashSet
var uniqueItems = new HashSet<string>();
// 需要键值对映射时使用Dictionary
var lookup = new Dictionary<int, string>();
- 避免装箱拆箱 “`csharp // 避免 var objects = new List
// 推荐
var numbers = new List
### 5.2 内存管理
1. **及时清理大型集合**
```csharp
largeList.Clear();
largeList.TrimExcess(); // 释放多余容量
使用Span
避免复制 int[] array = GetLargeArray(); Span<int> slice = array.AsSpan(100, 50); // 对slice的操作不会复制数据
5.3 线程安全
- 使用并发集合
csharp var concurrentDict = new ConcurrentDictionary<string, int>(); var concurrentQueue = new ConcurrentQueue<string>();
- 使用并发集合
读写锁保护 “`csharp private readonly ReaderWriterLockSlim _lock = new(); private readonly List
_list = new();
public void AddItem(string item) { _lock.EnterWriteLock(); try { _list.Add(item); } finally { _lock.ExitWriteLock(); } } “`
6. 总结
本章详细介绍了C#中的数组和集合类型:
- 数组基础:一维数组、多维数组、锯齿数组的声明、初始化和操作
- 数组算法:排序、查找、反转等常用算法的实现
- List
:动态数组的使用和高级操作 - Dictionary
:键值对存储和查找 - 其他集合:HashSet、Queue、Stack、LinkedList等的特点和应用
- 并发集合:线程安全的集合类型
- 实践应用:学生管理系统和数据分析工具的完整实现
- 性能优化:集合选择指南和最佳实践
关键要点: - 根据使用场景选择合适的集合类型 - 注意性能特性和内存使用 - 合理使用LINQ进行数据操作 - 在多线程环境中使用并发集合 - 预分配容量以提高性能
下一章预告: 下一章我们将学习面向对象编程的核心概念,包括类、对象、继承、封装和多态等重要特性。