GroupBy对字符串(hashcode碰撞)
我有一个字符串数组(大约2000),并且我想使用IEnumerable.GroupBy来组合相等的。
问题是有很多散列冲突,比如“神秘”和“好”。 这可能是由于GroupBy使用GetHashCode() ,它返回的int太小(或者类String的GetHashCode函数没有很好地实现)。
我想你可以尝试实现一个重写的GetHashCode函数或定义一个自定义IEqualityComparer并使用不同的哈希码,但没有任何方法可以直接或不同地比较它们吗? 我知道这需要更长的时间,但只有少量它是可以接受的。 我怎么能解决这个问题?
不论是否具有相同的哈希码,GroupBy在字符串上只会将相同的字符串组合在一起。 由于GroupBy使用哈希表下的哈希表,许多具有相同哈希代码的不同字符串可能会降低性能,但仍会给出正确的答案。
为了向你自己证明这一点,请注意,即使使用具有可怕哈希函数的自定义IEqualityComparer,GroupBy也可以很好地工作:
void Main()
{
var groups = new[] { "a", "a", "b", "b", "c", "c" }.GroupBy(s => s, new BadComparer())
.Select(g => string.Join(",", g))
.ToArray();
Console.WriteLine(string.Join(Environment.NewLine, groups));
// this prints:
// a,a
// b,b
// c,c
}
public class BadComparer : IEqualityComparer<string> {
public bool Equals(string a, string b) { return a == b; }
public int GetHashCode(string s) { return 0; }
}
还要注意,根据字符串本身而不是哈希码进行分组非常重要:
myStrings.GroupBy(s => s) // works
myStrings.GroupBy(s => s.GetHashCode()) // doesn't work
上一篇: GroupBy on strings (hashcode collision)
下一篇: What's the role of GetHashCode in the IEqualityComparer<T> in .NET?