如何构建能正确识别相同内容字节数组的HashSet?
解决HashSet<byte[]>无法识别内容相同数组的问题
这个坑我之前也踩过!核心原因是数组属于引用类型,HashSet<T>默认会用引用相等性来判断元素是否重复——也就是说,它只看两个变量是不是指向内存里同一个对象,而不会去对比数组里的内容。你代码里的b1和b2虽然字节完全一样,但它们是两个独立的对象实例,所以HashSet会把它们当成两个不同的元素,最终Count返回2就不奇怪了。
要让HashSet<byte[]>能基于内容判断重复,你需要给它传入一个自定义的相等比较器,实现针对字节数组内容的哈希计算和相等判断。
方法:自定义ByteArrayEqualityComparer
写一个实现IEqualityComparer<byte[]>的类,专门处理字节数组的内容比较:
public class ByteArrayEqualityComparer : IEqualityComparer<byte[]> { // 判断两个字节数组内容是否相等 public bool Equals(byte[] x, byte[] y) { // 处理null情况 if (x == null && y == null) return true; if (x == null || y == null) return false; // 长度不同直接不相等 if (x.Length != y.Length) return false; // 逐字节对比 for (int i = 0; i < x.Length; i++) { if (x[i] != y[i]) return false; } return true; } // 根据数组内容生成哈希码 public int GetHashCode(byte[] obj) { if (obj == null) return 0; int hash = 17; foreach (byte b in obj) { hash = hash * 31 + b.GetHashCode(); } return hash; } }
如何使用
初始化HashSet的时候,把这个比较器传进去就行:
void test() { byte[] b1 = new byte[] { 1, 2, 3 }; byte[] b2 = new byte[] { 1, 2, 3 }; HashSet<byte[]> set = new HashSet<byte[]>(new ByteArrayEqualityComparer()); set.Add(b1); set.Add(b2); Text = set.Count.ToString();// 现在会返回1,符合预期 }
额外说明
为什么默认不行?因为所有数组类型的Equals和GetHashCode方法都是继承自Object类的默认实现——Equals判断引用是否相同,GetHashCode基于对象内存地址生成。所以HashSet用这些默认逻辑时,自然不会关心数组内容。
内容的提问来源于stack exchange,提问作者ispiro
相关产品推荐
相关产品推荐

