ZetCode

C# HashSet

上次修改时间:2024 年 1 月 19 日

在本文中,我们将展示如何在 C# 中使用 HashSet 集合。

HashSet

HashSet 表示一组值。它不包含重复元素。该集合模拟了数学集合的抽象。

HashSet 不提供元素的排序。 如果我们需要保持顺序,我们可以使用 SortedSet 集合。

C# HashSet 计数元素

Count 属性返回 HashSet 中元素的数量。

Program.cs
var brands = new HashSet<string>();

brands.Add("Wilson");
brands.Add("Nike");
brands.Add("Volvo");
brands.Add("IBM");
brands.Add("IBM");

int nOfElements = brands.Count;

Console.WriteLine($"The set contains {nOfElements} elements");
Console.WriteLine(string.Join(", ", brands));

我们有一组品牌。

var brands = new HashSet<string>();

创建一个新的 HashSet

brands.Add("Wilson");

使用 Add 方法将元素添加到集合中。

int nOfElements = brands.Count;

我们使用 Count 属性获取元素的数量。

$ dotnet run
The set contains 4 elements
Wilson, Nike, Volvo, IBM

C# HashSet 删除元素

在下一个示例中,我们从 HashSet 中删除元素。

Program.cs
var brands = new HashSet<string>
{
    "Wilson", "Nike", "Volvo", "Kia", "Lenovo"
};

Console.WriteLine(string.Join(", ", brands));

brands.Remove("Kia");
brands.Remove("Lenovo");

Console.WriteLine(string.Join(", ", brands));

brands.Clear();

if (brands.Count == 0)
{
    Console.WriteLine("The brands set is empty");
}

var words = new HashSet<string>
{
    "sky", "blue", "cup", "cold", "cloud", "pen", "bank"
};

words.RemoveWhere(word => word.Length == 3);
Console.WriteLine(string.Join(", ", words));

使用 RemoveClearRemoveWhere 删除元素。

brands.Remove("Kia");

使用 Remove 删除单个元素。

brands.Clear();

使用 Clear 删除所有元素。

words.RemoveWhere(word => word.Length == 3);

使用 RemoveWhere,我们删除满足给定条件的元素。

$ dotnet run
Wilson, Nike, Volvo, Kia, Lenovo
Wilson, Nike, Volvo
The brands set is empty
blue, cold, cloud, bank

C# HashSet 循环

我们可以使用 foreach 和 while 关键字循环访问 HashSet

Program.cs
var words = new HashSet<string>
{
    "sky", "blue", "cup", "cold", "cloud", "pen", "bank"
};

foreach (var word in words)
{
    Console.WriteLine(word);
}

Console.WriteLine("----------------------");

var it = words.GetEnumerator();

while (it.MoveNext())
{
    Console.WriteLine(it.Current);
}

在此示例中,我们使用 foreach 和 while 迭代 HashSet 中的单词。

$ dotnet run
sky
blue
cup
cold
cloud
pen
bank
----------------------
sky
blue
cup
cold
cloud
pen
bank

C# HashSet Contains

Contains 方法确定 HashSet 是否包含指定的元素。

Program.cs
var words = new HashSet<string>
{
    "sky", "blue", "cup", "cold", "cloud", "pen", "bank"
};

Console.WriteLine(words.Contains("sky"));
Console.WriteLine(words.Contains("water"));

Console.WriteLine("-----------------");

var users = new HashSet<User>
{
    new ("John Doe", "gardener"),
    new ("Roger Roe", "driver"),
    new ("Lucy Smith", "teacher")
};

var u1 = new User("John Doe", "gardener");
var u2 = new User("Jane Doe", "student");

Console.WriteLine(users.Contains(u1));
Console.WriteLine(users.Contains(u2));

record User(string Name, string Occupation);

我们有两个 HashSet 集合。

var words = new HashSet<string>
{
    "sky", "blue", "cup", "cold", "cloud", "pen", "bank"
};

Console.WriteLine(words.Contains("sky"));
Console.WriteLine(words.Contains("water"));

我们检查一个单词的 HashSet 是否包含这两个指定的单词。

var u1 = new User("John Doe", "gardener");
var u2 = new User("Jane Doe", "student");

Console.WriteLine(users.Contains(u1));
Console.WriteLine(users.Contains(u2));

C# 记录包含 EqualsGetHashCode 方法的默认实现; 因此,Contains 方法的工作方式符合我们的预期。

$ dotnet run
True
False
-----------------
True
False

对于类,我们需要实现 EqualsGetHashCode 方法。

Program.cs
var users = new HashSet<User>
{
    new ("John Doe", "gardener"),
    new ("Roger Roe", "driver"),
    new ("Lucy Smith", "teacher")
};

var u1 = new User("John Doe", "gardener");
var u2 = new User("Jane Doe", "student");

Console.WriteLine(users.Contains(u1));
Console.WriteLine(users.Contains(u2));


class User(string name, string occupation)
{
    string Name { get; } = name;
    string Occupation { get; } = occupation;

    public override bool Equals(object? obj)
    {
        return obj is User user &&
               Name == user.Name &&
               Occupation == user.Occupation;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Occupation);
    }
}

在此示例中,我们有一个用户对象的 HashSet。 由于该对象使用 class 关键字定义,因此我们添加了 EqualsGetHashCode 方法的实现。

$ dotnet run
True
False

C# HashSet

HashSet 包含一组特定于集合的方法。

Program.cs
var vals1 = new HashSet<int> { 1, 2, 3, 4, 5 };
var vals2 = new HashSet<int> { 6, 7, 8, 9, 10 };

vals1.UnionWith(vals2);
Console.WriteLine(string.Join(", ", vals1));

var vals3 = new HashSet<int> { 1, 2, 3, 4, 5 };
var vals4 = new HashSet<int> { 3, 4, 5, 6, 7 };

vals3.IntersectWith(vals4);
Console.WriteLine(string.Join(", ", vals3));

我们使用 UnionWithIntersectWith 方法。

vals1.UnionWith(vals2);

UnionWith 方法修改 HashSet 对象以包含来自两个集合的元素。

vals3.IntersectWith(vals4);

IntersectWith 方法修改 HashSet 对象以包含两个对象中都存在的元素。

$ dotnet run
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
3, 4, 5

C# SortSet

SortedSet 表示一组按排序顺序维护的对象。

Program.cs
var vals = new SortedSet<int> { 5, 2, 1, 4, 3, 7, 6 };
Console.WriteLine(string.Join(", ", vals));

var words = new SortedSet<string>
{
    "sky", "blue", "cup", "cold", "cloud", "pen", "bank"
};

Console.WriteLine(string.Join(", ", words));

var users = new SortedSet<User>
{
    new ("Robin", "bookseller"),
    new ("John", "gardener"),
    new ("John", "writer"),
    new ("Janet", "teacher"),
    new ("Andrew", "driver"),
    new ("Lucy", "accountant")
};

Console.WriteLine(string.Join("\n", users));

record User(string Name, string Occupation) : IComparable<User>
{
    public int CompareTo(User? other) => Occupation.CompareTo(other!.Occupation);
}

我们有整数、字符串和用户的 SortedSet

$ dotnet run
1, 2, 3, 4, 5, 6, 7
bank, blue, cloud, cold, cup, pen, sky
User { Name = Lucy, Occupation = accountant }
User { Name = Robin, Occupation = bookseller }
User { Name = Andrew, Occupation = driver }
User { Name = John, Occupation = gardener }
User { Name = Janet, Occupation = teacher }
User { Name = John, Occupation = writer }

来源

HashSet 类 - 语言参考

在本文中,我们使用了 C# HashSet。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程