我有一个字符串数组(约2000),我想使用 IEnumerable.GroupBy 对相等的字符串进行分组。
问题是虽然存在许多哈希冲突,例如“神秘”和“井”。这可能是因为GroupBy使用了 GetHashCode(),它返回的int太小了(或者String类的GetHashCode函数没有很好地实现)。
我想您可以尝试实现重写的 GetHashCode 函数或定义自定义 IEqualityComparer 并使用不同的哈希码,但是没有任何方法可以直接比较它们或不同?我知道这需要更长的时间,但只需少量就可以接受。我怎么能解决这个问题?
答案 0 :(得分:2)
GroupBy on strings只会将相同的字符串组合在一起,无论它们是否具有相同的哈希码。由于GroupBy在底层使用哈希表,因此许多具有相同哈希码的不同字符串可能会略微降低性能,但仍会给出正确的答案。
为了证明这一点,请注意GroupBy即使使用具有可怕散列函数的自定义IEqualityComparer也能正常工作:
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