C#:HashSet<T> 去重

HashSet<T> 底层基于哈希表实现,去重依赖 `GetHashCode()` 和 `Equals()` 两个方法。添加元素时,先计算哈希码定位桶位置,若哈希冲突则调用 `Equals()` 比较内容。若两者均判定相等,则视为重复元素不予添加。

关键机制:

  1. 哈希分流:通过 `GetHashCode()` 快速定位存储桶,平均时间复杂度 O(1)。

  2. 精确比对:哈希值相同(冲突)时,才执行 `Equals()` 进行逐字段比较。

  3. 契约约束:若 `Equals()` 返回 true,`GetHashCode()` 必须返回相同值;反之不成立。

常见陷阱与修复:

* 引用类型默认行为:未重写上述两方法时,默认比较内存地址,导致内容相同的不同对象被视为不重复。

* 性能优化:`Add()` 返回 bool 值,直接利用返回值判断是否为新元素,避免额外调用 `Contains()` 造成二次哈希查找。

using System;

using System.Collections.Generic;

// 方案1:使用 record (C9+),编译器自动生成正确的 GetHashCode 和 Equals

public record Person(string Name, int Age);

// 方案2:传统 class 需手动重写

public class Product

{

public string Id { get; set; }

public string Name { get; set; }

public override bool Equals(object obj)

{

if (obj is Product other)

return Id == other.Id; // 根据业务主键判断

return false;

}

public override int GetHashCode()

{

return HashCode.Combine(Id); // 确保参与 Equals 的字段也参与哈希计算

}

}

class Program

{

static void Main()

{

// 1. 基础类型去重 (int/string 已内置正确实现)

var numbers = new List<int> { 1, 2, 2, 3, 4, 4, 5 };

var uniqueNumbers = new HashSet<int>(numbers); // 构造函数直接去重

Console.WriteLine($"Unique Numbers: {string.Join(", ", uniqueNumbers)}");

// 2. 复杂对象去重 (使用 record)

var people = new List<Person>

{

new Person("Alice", 25),

new Person("Bob", 30),

new Person("Alice", 25) // 重复

};

var uniquePeople = new HashSet<Person>(people);

// 3. 流式处理去重 (利用 Add 返回值,避免二次查找)

var rawIds = new List<string> { "A01", "A02", "A01", "A03" };

var seenIds = new HashSet<string>();

foreach (var id in rawIds)

{

if (seenIds.Add(id)) // Add 返回 true 表示是新元素,false 表示已存在

{

Console.WriteLine($"Processing new ID: {id}");

}

}

}

}

```

相关推荐
吃一碗粉只付一碗钱7 小时前
12-给SPA友好的401和403响应
c#·状态模式
caimouse13 小时前
MonoDevelop 编译用户应用程序时调用的是哪个编译器
c#
will_net15 小时前
apollo 站点部署&C#接入
开发语言·c#·apollo
吾与谁归in1 天前
C#脚本工具,支持智能提示自动补全(WPF + Roslyn + AvalonEdit)
开发语言·c#·wpf
昂好的day1 天前
WPF 从零入门(上):WPF 是什么、XAML 语法、布局与样式全解
开发语言·c#·wpf
吃一碗粉只付一碗钱2 天前
10-令牌里的用户主键不要明文
服务器·数据库·sql·sqlserver·c#
胖纸不争2 天前
EnergyStarZ:让 Windows 后台进程给前台让路的能效管理器(v1.2 发布)
windows·性能优化·c#·win32·ef core
曹牧2 天前
C#:The operation has timed out
开发语言·c#
He BianGu2 天前
【WPF-Control教程】IOC 依赖注入
c#·wpf·wpf-control