c# 容器笔记

c#与c++的相似容器

c#中和std::set 的用法相似的容器

在 C# 中,和 C++ 中的 std::set 用法相似的容器是 HashSet<T>SortedSet<T>。这两者都实现了集合的功能,但有一些不同的特点。

HashSet<T>

  • 无序集合:不保证元素的顺序。
  • 快速查找:基于哈希表,查找、添加和删除操作的平均时间复杂度为 O(1)。
  • 唯一性:不允许重复元素。
用法示例:
csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        HashSet<int> hashSet = new HashSet<int>();

        // 添加元素
        hashSet.Add(1);
        hashSet.Add(2);
        hashSet.Add(3);

        // 尝试添加重复元素
        bool added = hashSet.Add(3); // added will be false because 3 is already in the set

        // 检查元素是否存在
        bool contains = hashSet.Contains(2); // contains will be true

        // 删除元素
        hashSet.Remove(2);

        // 遍历元素
        foreach (int item in hashSet)
        {
            Console.WriteLine(item);
        }
    }
}

SortedSet<T>

  • 有序集合:元素按排序顺序存储(默认按升序排列)。
  • 较慢查找:基于红黑树,查找、添加和删除操作的平均时间复杂度为 O(log n)。
  • 唯一性:不允许重复元素。
用法示例:
csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        SortedSet<int> sortedSet = new SortedSet<int>();

        // 添加元素
        sortedSet.Add(3);
        sortedSet.Add(1);
        sortedSet.Add(2);

        // 尝试添加重复元素
        bool added = sortedSet.Add(2); // added will be false because 2 is already in the set

        // 检查元素是否存在
        bool contains = sortedSet.Contains(1); // contains will be true

        // 删除元素
        sortedSet.Remove(1);

        // 遍历元素
        foreach (int item in sortedSet)
        {
            Console.WriteLine(item); // 输出为 2, 3 因为集合是有序的
        }
    }
}

选择 HashSet<T> 还是 SortedSet<T>

  • 如果需要快速查找和不关心元素的顺序 ,选择 HashSet<T>
  • 如果需要元素按顺序存储和查找稍微慢一些也能接受 ,选择 SortedSet<T>

这两个集合类都实现了 ISet<T> 接口,因此在使用集合操作时有类似的 API。根据你的具体需求选择适合的集合类型。

c# 中与pari相似的容器

在 C# 中,与 C++ 中的 std::pair 类似的容器是 TupleKeyValuePair

Tuple

Tuple 是一个通用的数据结构,可以存储一组相关的值。以下是一个示例,展示如何使用 Tuple

csharp 复制代码
using System;

class Program
{
    static void Main()
    {
        // 创建一个Tuple来存储两个相关的值
        Tuple<int, string> person = new Tuple<int, string>(1, "John Doe");

        // 访问Tuple的元素
        int id = person.Item1;
        string name = person.Item2;

        Console.WriteLine($"ID: {id}, Name: {name}");
    }
}

KeyValuePair

KeyValuePair 是一种特定类型的容器,常用于字典(Dictionary)中来存储键值对。以下是一个示例,展示如何使用 KeyValuePair

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个Dictionary来存储键值对
        Dictionary<int, string> people = new Dictionary<int, string>();

        // 添加键值对到Dictionary中
        people.Add(1, "John Doe");
        people.Add(2, "Jane Doe");

        // 访问Dictionary中的元素
        foreach (KeyValuePair<int, string> person in people)
        {
            Console.WriteLine($"ID: {person.Key}, Name: {person.Value}");
        }
    }
}

使用 KeyValuePair 单独创建键值对

你也可以单独创建 KeyValuePair 对象,而不使用 Dictionary

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个KeyValuePair来存储两个相关的值
        KeyValuePair<int, string> person = new KeyValuePair<int, string>(1, "John Doe");

        // 访问KeyValuePair的元素
        int id = person.Key;
        string name = person.Value;

        Console.WriteLine($"ID: {id}, Name: {name}");
    }
}

比较 Tuple 和 KeyValuePair

  • Tuple 可以包含多个值(不仅限于两个),可以创建 Tuple<T1, T2, T3, ...>
  • KeyValuePair 是一种特定的容器,通常用于字典数据结构,具有明确的键和值。

根据你的具体需求,选择合适的数据结构。如果你需要存储一对值,并且它们是键值对关系,KeyValuePair 是一个不错的选择。如果你需要存储多于两个的相关值,Tuple 会更合适。

c# List 求最大值

在 C# 中,可以使用 List<T> 来存储一系列元素,并通过多种方式来求取最大值。最常用的方法是使用 LINQ 提供的 Max 方法。以下是几种常见的求最大值的方法:

使用 LINQ 的 Max 方法

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 10, 3, 8, 15 };

        // 使用 LINQ 的 Max 方法
        int maxNumber = numbers.Max();

        Console.WriteLine($"The maximum number is {maxNumber}");
    }
}

使用循环求最大值

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 10, 3, 8, 15 };

        // 使用循环求最大值
        int maxNumber = int.MinValue;
        foreach (int number in numbers)
        {
            if (number > maxNumber)
            {
                maxNumber = number;
            }
        }

        Console.WriteLine($"The maximum number is {maxNumber}");
    }
}

使用 IComparer<T>List<T>.Sort 方法

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 10, 3, 8, 15 };

        // 使用 IComparer<T> 和 List<T>.Sort 方法
        numbers.Sort();
        int maxNumber = numbers[numbers.Count - 1];

        Console.WriteLine($"The maximum number is {maxNumber}");
    }
}

求取对象列表中的最大值

如果你有一个包含对象的列表,并且想根据对象的某个属性求最大值,可以使用 LINQMax 方法并传递一个选择器。

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        List<Person> people = new List<Person>
        {
            new Person { Name = "Alice", Age = 30 },
            new Person { Name = "Bob", Age = 25 },
            new Person { Name = "Charlie", Age = 35 }
        };

        // 使用 LINQ 的 Max 方法求最大年龄
        int maxAge = people.Max(p => p.Age);

        Console.WriteLine($"The maximum age is {maxAge}");
    }
}

这些方法都能有效地求取 List<T> 中的最大值,根据具体需求选择合适的方法。一般情况下,使用 LINQMax 方法最为简洁和方便。

判断List是否为空

在 C# 中,可以通过多种方式来判断一个 List<T> 是否为空。以下是一些常见的方法:

使用 Count 属性

这是最直接的方法,通过检查 List<T>Count 属性来判断是否为空。

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>();

        // 使用 Count 属性判断是否为空
        if (numbers.Count == 0)
        {
            Console.WriteLine("The list is empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }
}

使用 Any 方法

LINQ 提供的 Any 方法也可以用来检查列表是否为空。Any 方法返回一个布尔值,指示是否存在任何元素。

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>();

        // 使用 LINQ 的 Any 方法判断是否为空
        if (!numbers.Any())
        {
            Console.WriteLine("The list is empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }
}

直接检查 List<T> 是否为 null

在实际应用中,还应该考虑列表本身是否为 null。在这种情况下,先判断列表是否为 null,再判断列表是否为空。

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = null;

        // 检查列表是否为 null
        if (numbers == null)
        {
            Console.WriteLine("The list is null.");
        }
        else if (numbers.Count == 0)
        {
            Console.WriteLine("The list is empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }
}

综合判断(处理 null 和空列表)

可以将判断 null 和空列表的逻辑合并为一个方法,方便重复使用:

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = null;

        if (IsNullOrEmpty(numbers))
        {
            Console.WriteLine("The list is null or empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }

    static bool IsNullOrEmpty<T>(List<T> list)
    {
        return list == null || list.Count == 0;
    }
}

这些方法都可以有效地判断 List<T> 是否为空。根据具体场景的需求选择合适的方法。一般情况下,使用 Count 属性或者 LINQAny 方法最为常见和简洁。如果需要同时处理 null 和空列表的情况,可以使用综合判断方法。

取List第一个元素

在 C# 中,可以通过多种方式获取 List<T> 的第一个元素。以下是一些常见的方法:

使用索引

这是最直接的方法,通过索引来访问 List<T> 的第一个元素。需要注意的是,在访问之前应该检查列表是否为空,以避免 IndexOutOfRangeException 异常。

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        if (numbers.Count > 0)
        {
            int firstElement = numbers[0];
            Console.WriteLine("The first element is: " + firstElement);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }
}

使用 First 方法

LINQ 提供的 First 方法可以用于获取列表的第一个元素。需要导入 System.Linq 命名空间。First 方法在列表为空时会抛出 InvalidOperationException 异常,因此使用之前可以检查列表是否为空,或者使用 FirstOrDefault 方法。

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        if (numbers.Any())
        {
            int firstElement = numbers.First();
            Console.WriteLine("The first element is: " + firstElement);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }
}

使用 FirstOrDefault 方法

FirstOrDefault 方法在列表为空时不会抛出异常,而是返回默认值。对于引用类型,默认值是 null;对于值类型,默认值是类型的默认值(例如 int 的默认值是 0)。

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        int firstElement = numbers.FirstOrDefault();
        if (numbers.Any())
        {
            Console.WriteLine("The first element is: " + firstElement);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }
}

综合判断并获取第一个元素的方法

可以将判断列表是否为空和获取第一个元素的逻辑合并到一个方法中:

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        int? firstElement = GetFirstElement(numbers);
        if (firstElement.HasValue)
        {
            Console.WriteLine("The first element is: " + firstElement.Value);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }

    static int? GetFirstElement(List<int> list)
    {
        if (list == null || list.Count == 0)
        {
            return null;
        }
        return list[0];
    }
}

在这个例子中,GetFirstElement 方法返回一个 Nullable<int>,即 int? 类型,以便处理空列表的情况。在调用该方法后,可以检查返回值是否有值(即 HasValue 属性),然后再使用值(通过 Value 属性)。

这些方法都可以有效地获取 List<T> 的第一个元素。根据具体的应用场景选择合适的方法。如果需要同时处理 null 和空列表的情况,可以使用综合判断的方法。

判断HashSet中是否有这个元素

在 C# 中,可以使用 HashSet<T>Contains 方法来判断集合中是否包含特定元素。HashSet<T> 是一个非常高效的数据结构,用于存储唯一值,并且其查找操作的平均时间复杂度为 O(1)。

下面是一个示例代码,展示如何在 HashSet<int> 中判断是否包含某个元素:

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个HashSet并添加一些元素
        HashSet<int> numbers = new HashSet<int> { 1, 2, 3, 4, 5 };

        // 要查找的元素
        int elementToFind = 3;

        // 判断HashSet中是否包含该元素
        if (numbers.Contains(elementToFind))
        {
            Console.WriteLine($"HashSet contains the element {elementToFind}.");
        }
        else
        {
            Console.WriteLine($"HashSet does not contain the element {elementToFind}.");
        }
    }
}

在上面的示例中,我们首先创建了一个包含整数的 HashSet 并添加了一些元素。然后,我们使用 Contains 方法检查 HashSet 中是否存在指定的元素 elementToFind

解释

  • HashSet<int> numbers = new HashSet<int> { 1, 2, 3, 4, 5 };:创建一个 HashSet 并初始化一些整数元素。
  • int elementToFind = 3;:要查找的元素。
  • if (numbers.Contains(elementToFind)):使用 Contains 方法判断 HashSet 中是否包含 elementToFind
  • 如果包含,输出 "HashSet contains the element {elementToFind}."。
  • 否则,输出 "HashSet does not contain the element {elementToFind}."。

Contains 方法返回一个布尔值,指示 HashSet 是否包含指定的元素。这使得查找操作变得非常简单和高效。

tuple 求double 求出最小值对应的项

要在一个包含 Tuple<int, double>List 中找到 double 最小值对应的 Tuple<int, double> 项,可以使用 LINQ。这里是一个示例代码,演示如何实现这一点:

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        // 创建一个包含 Tuple<int, double> 的列表
        List<Tuple<int, double>> list = new List<Tuple<int, double>>()
        {
            new Tuple<int, double>(1, 10.5),
            new Tuple<int, double>(2, 5.75),
            new Tuple<int, double>(3, 7.3),
            new Tuple<int, double>(4, 3.8),
            new Tuple<int, double>(5, 9.1)
        };

        // 使用 LINQ 来找到 double 的最小值对应的项
        var minItem = list.Aggregate((min, next) => next.Item2 < min.Item2 ? next : min);

        Console.WriteLine($"The item with the minimum double value is: ({minItem.Item1}, {minItem.Item2})");
    }
}

解释

  1. List<Tuple<int, double>> : 创建一个包含 Tuple<int, double> 的列表。每个元组包含一个整数和一个双精度浮点数。

  2. LINQ Aggregate 方法 : list.Aggregate((min, next) => next.Item2 < min.Item2 ? next : min) 使用 LINQ 的 Aggregate 方法来找到 double 最小值对应的项。这里的 Aggregate 方法接受两个参数,minnext,并通过比较 next.Item2min.Item2 来更新 min,从而找到具有最小 double 值的项。

  3. 输出结果 : 将找到的具有最小 double 值的项打印出来。

输出结果

运行上述代码后,控制台将输出:

The item with the minimum double value is: (4, 3.8)

使用其他方法

你还可以使用 LINQ 的 OrderBy 方法来实现同样的结果:

csharp 复制代码
var minItem = list.OrderBy(t => t.Item2).First();
Console.WriteLine($"The item with the minimum double value is: ({minItem.Item1}, {minItem.Item2})");

这种方法首先按照 double 值对列表进行排序,然后使用 First() 方法获取排序后的第一个元素,即 double 值最小的项。

这两种方法都可以找到 Tuple<int, double> 列表中 double 最小值对应的项。选择哪种方法取决于个人偏好和具体场景。

相关推荐
xlsw_44 分钟前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹2 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭2 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫2 小时前
泛型(2)
java
超爱吃士力架2 小时前
邀请逻辑
java·linux·后端
南宫生2 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石3 小时前
12/21java基础
java
李小白663 小时前
Spring MVC(上)
java·spring·mvc
冷眼看人间恩怨3 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
GoodStudyAndDayDayUp3 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea