我已经使用以下代码在类中实现了IEquatable接口.
public bool Equals(ClauseBE other)
{
if (this._id == other._id)
{
return true;
}
return false;
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return base.Equals(obj);
}
if (!(obj is ClauseBE))
{
throw new InvalidCastException("The 'obj' argument is not a ClauseBE object.");
}
return Equals(obj as ClauseBE);
}
public override int GetHashCode()
{
return this._id.GetHashCode();
}
public static bool operator ==(ClauseBE a, ClauseBE b)
{
// cast to object so we call the overloaded Equals function …Run Code Online (Sandbox Code Playgroud) 我有一个看起来像这样的课程.
public class Point : IEquatable<Point>
{
public int _xValue {get;set;}
public double _yValue {get;set;}
public Point(int x, double y)
{
_xValue = x;
_yValue = y;
}
public override bool Equals(object obj)
{
return Equals(obj as Point);
}
public bool Equals(Point obj)
{
return obj != null && obj._xValue == this._xValue && obj._yValue == this._yValue;
}
}
Run Code Online (Sandbox Code Playgroud)
我必须实现该GetHashCode功能,以便我可以将它用作字典键.但是我不清楚GetHashCode在这种情况下函数必须返回什么.有人可以帮我吗?
我最近在几次关于Hashtables的访谈中进行了深入研究,并且何时需要覆盖GetHashCode().讨论一直在深入和深入,直到我全身心投入.
我现在正在做一些研究,以涵盖下一次准备好的一切.
我找到了这篇我想分享的优秀文章:http: //msdn.microsoft.com/en-us/library/ms379571(VS80).aspx #datastructures20_2_topic5
1)我感觉不太舒服的事实是字典是基于哈希的,但列表显然不是.这只是意味着在List <>和Array []中搜索是线性的,而在字典或散列表中搜索是不变的,因此更快?这都是它的全部吗?
2)如果我使用类作为字典中的键,我需要根据任何必需的标识字段覆盖该类的GetHashcode()以使实例唯一.但是,仍然可能发生两个ID字段相等并且将生成相同的哈希码?如果这是两个实例与相同哈希码冲突期间发生的情况?
3)如何解决碰撞?我在文章中读到了关于Hashtable和Chaining for the Dictionary的碰撞情况下的rehashing方法.但我仍然不确定它是如何工作的,因为我不是数学天才.: - \任何人都可以更好地解释它是如何工作的?
非常感谢,Kave
我使用以下查询
var queryList1Only = (from file in list1
select file).Except(list2, myFileCompare);
Run Code Online (Sandbox Code Playgroud)
同时myFileCompare根据名称和长度比较2个文件.
如果list1和list2很小(在我测试时说100个文件),查询返回结果,然后我将list1增加到30,000个文件,list2增加到20,000个文件,查询现在说"Function Evaluation Timed Out".
我在网上搜索,发现调试可能会导致它,所以我删除了所有断点并运行代码,现在程序只是冻结,没有任何输出,queryList1Only我试图打印出来检查它.
编辑:这是myFileCompare的代码
class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
public FileCompare() { }
public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
{
return (f1.Name == f2.Name && f1.Directory.Name == f2.Directory.Name &&
f1.Length == f2.Length);
}
// Return a hash that reflects the comparison criteria. According to the
// rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
// also …Run Code Online (Sandbox Code Playgroud) 我正在设计一个类库,它有一堆类型的方法"EnsureXXX".只要调用代码需要某些东西而不需要特定于参数的初始化,就会调用此方法的思想.它类似于EnsureChildControlsASP.Net 的方法,但有参数作为鉴别器.
例如:
public static class SomeUtilityClass {
public static void EnsureSomething(string arg1, int arg2, object arg3)
{
// Logic should be called once for each args combination
}
}
public class CallerClass
{
public void Foo()
{
SomeUtilityClass.EnsureSomething("mycustomerid", 4, myData.SomeProperty);
}
public void Foo2()
{
SomeUtilityClass.EnsureSomething("mycustomerid", 4, myData.SomeProperty);
}
}
Run Code Online (Sandbox Code Playgroud)
因为这样的模式将在几个地方重用并经常调用,所以我必须将性能作为目标.我还必须有一个线程安全的方法.
为此,我写了一个小实用程序类:
public sealed class CallHelper
{
private static readonly HashSet<int> g_YetCalled = new HashSet<int>();
private static readonly object g_SyncRoot = new object();
public static void EnsureOnce(Type …Run Code Online (Sandbox Code Playgroud) 我有一个带有字符串属性的类,我需要重写GetHashCode()方法。
class A
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
第一个想法是做这样的事情:
public override int GetHashCode()
{
return Prop1.GetHashCode() ^ Prop2.GetHashCode() ^ Prop3.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
第二个想法是:
public override int GetHashCode()
{
return String.Join(";", new[] {Prop1, Prop2, Prop3}).GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
什么是最好的方法?
我有一个由两个字符串和一个枚举组成的类.我正在尝试将此类的实例用作字典中的键.不幸的是,我似乎没有正确实现IEquatable.这是我如何做到的:
public enum CoinSide
{
Heads,
Tails
}
public class CoinDetails : IComparable, IEquatable<CoinDetails>
{
private string denomination;
private string design;
private CoinSide side;
//...
public int GetHashCode(CoinDetails obj)
{
return string.Concat(obj.Denomination, obj.Design, obj.Side.ToString()).GetHashCode();
}
public bool Equals(CoinDetails other)
{
return (this.Denomination == other.Denomination && this.Design == other.Design && this.Side == other.Side);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我似乎仍然无法在我的字典中查找项目.此外,以下测试失败:
[TestMethod]
public void CoinDetailsHashCode()
{
CoinDetails a = new CoinDetails("1POUND", "1997", CoinSide.Heads);
CoinDetails b = new CoinDetails("1POUND", "1997", CoinSide.Heads);
Assert.AreEqual(a.GetHashCode(), b.GetHashCode());
}
[TestMethod]
public void …Run Code Online (Sandbox Code Playgroud) 说我有一个包含这样的对象的列表:
public class Person
{
private string _name;
private string _id;
private int _age;
public Person
{
}
// Accessors
}
public class ManipulatePerson
{
Person person = new Person();
List<Person> personList = new List<Person>;
// Assign values
private void PopulateList();
{
// Loop
personList.Add(person);
// Check if every Person has a unique ID
}
}
Run Code Online (Sandbox Code Playgroud)
我想检查每个人都有一个唯一的ID.我想返回一个布尔值true/false,具体取决于ID是否唯一.这是我用LINQ可以实现的吗?
给定(简化说明)
我们的一项服务在内存中有很多实例.大约85%是独一无二的.我们需要对这些项目进行非常快速的基于密钥的访问,因为它们在单个堆栈/调用中经常被查询.这个单一的上下文非常优化性能.
所以我们开始将它们放入字典中.表现还可以.
在这种情况下,尽可能快地访问项目是最重要的.确保在读取发生时没有写入操作.
问题
与此同时,我们达到了字典可以存储的项目数量的限制.
Die Arraydimensionen haben den unterstützten Bereich überschritten.
bei System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes)
bei System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
Run Code Online (Sandbox Code Playgroud)
这转化为The array dimensions have exceeded the supported range.
像Memcached这样的解决方案在这个特定情况下太慢了.它是一个封装在单个服务中的独立的非常具体的用例
因此,我们正在寻找替代此特定方案的字典.
目前我找不到一个支持这个.我错过了什么吗?有人能指出我吗?
作为替代方案,如果不存在,我们正在考虑自己实施一个.
我们想到了两种可能性.从头开始构建或包装多个词典.
包装多个词典
搜索一个项目时,我们可以看一下HasCode键,并使用它的起始编号作为包装词典列表的索引.虽然这似乎很容易让我闻到,但这意味着哈希码计算两次(内部字典一次由我们一次)(这种情况真的非常具有性能).
我知道像字典那样交换基类是绝对的最后一种可能性,我想避免它.但是目前看起来没有办法让对象更加独特,或者从数据库中获取字典的性能或者在其他地方保存性能.
我也意识到"要注意优化",但较低的性能会严重影响其背后的业务需求.
对于Delphi项目(使用RAD Studio XE7构建),我想创建一个画笔字典.每个字典项包含一个TMyBrush对象作为键,描述要检索的画笔,以及GDI +画笔作为值.
TMyBrush类包含3个字段
在我的字典中,我想根据他的特征检索画笔,而不是他的实例.例如,我希望通过创建本地TMyBrush实例,将其配置为黑色实体,并使用TryGetValue()函数获取匹配的GDI +值,从我的字典中获取黑色实心画笔.为此,我创建了一个TMyBrushComparer.
编写Equals()函数对我来说不是问题.但是我不知道编写GetHashCode()函数的最佳做法是什么.我倾向于写一个这样的函数:
function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;
Run Code Online (Sandbox Code Playgroud)
但是我觉得这不是一个很好的做法,这是正确的吗?那么,为我的TMyBrushComparer编写一个好的GetHashCode()函数的最佳实践是什么?
问候
c# ×8
.net ×3
dictionary ×2
gethashcode ×2
iequatable ×2
linq ×2
.net-4.6.1 ×1
algorithm ×1
collections ×1
compare ×1
delphi ×1
hash ×1
hashcode ×1
list ×1
object ×1
performance ×1
tdictionary ×1