我在谷歌应用引擎中有一个工作正常.我意识到我忘记实现的JDO增强对象中的一个等于和hashCode(我需要在一个集合中使用该对象).所以我做了.我没有在这些实现中做任何特别的事情,事实上我只是使用Eclipse来生成它们.像这样:
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent
private String appleId;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((appleId == null) ? 0 : appleId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (appleId == null) {
if (other.appleId != null) …Run Code Online (Sandbox Code Playgroud) 我有一个大字典,其中键是十进制的,但System.Decimal的GetHashCode()非常糟糕.为了证明我的猜测,我运行了一个带有100.000 neigboring小数的for循环并检查了分布.100.000个不同的十进制数仅使用2个(两个!!!)不同的哈希码.
十进制表示为16个字节.就像Guid一样!但是Guid的GetHashCode()发行版非常好.如何在C#中将小数转换为Guid尽可能便宜? 不安全的代码没问题!
编辑:请求测试,所以这里是代码:
decimal d = 96000000000000000000m;
Dictionary<int, int> hashcount = new Dictionary<int, int>();
int length = 100000;
for (int i = 0; i < length; i++)
{
int hashcode = d.GetHashCode();
int n;
if (hashcount.TryGetValue(hashcode, out n))
{
hashcount[hashcode] = n + 1;
}
else
{
hashcount.Add(hashcode, 1);
}
d++;
}
Console.WriteLine(hashcount.Count);
Run Code Online (Sandbox Code Playgroud)
这打印7.我不记得给我2的起始小数.
我已经设置了一个表示单词的循环链表数据结构,列表中的每个元素都是单词中的一个字母.在我的问题的底部是列表的类定义和列表的元素.
列表数据结构的目的是能够比较循环词.所以......"picture"和"turepic"是相同的循环词,所以这两个列表是相同的.
所以我equals()在比较两个列表时会覆盖,而且我已经读过,每当你必须覆盖时equals(),你也必须覆盖hashCode().但是,我真的不知道如何做到这一点.
我应该如何为我设置的内容定义一个好的hashCode?我应该考虑什么?在"picture"和"turepic"的例子中,两个列表是相同的,因此它们的hashCode需要相同.有任何想法吗?
谢谢,Hristo
public class Letter {
char value;
Letter theNextNode;
/**
* Default constructor for an element of the list.
*
* @param theCharacter - the value for this node.
*/
Letter(char theCharacter) {
this.value = theCharacter;
}
}
public class CircularWord {
/*
* Class Variables
*/
Letter head;
Letter tail;
Letter theCurrentNode;
int iNumberOfElements;
/**
* Default Constructor. All characters that make up 'theWord' are stored in a
* …Run Code Online (Sandbox Code Playgroud) 我有一个有float田地的课.例如:
public class MultipleFields {
final int count;
final float floatValue;
public MultipleFields(int count, float floatValue) {
this.count = count;
this.floatValue = floatValue;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要能够按值比较实例.现在我该如何正确实施 equals&hashCode?
通常的方式来实现equals,并hashCode是只考虑各个领域.例如,Eclipse将生成以下内容equals:
public boolean equals(Object obj) {
// irrelevant type checks removed
....
MultipleFields other = (MultipleFields) obj;
if (count != other.count)
return false;
if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
(和类似的hashCode,基本上计算count* 31 + Float.floatToIntBits(floatValue)).
这个问题是我的FP值受到舍入错误的影响(它们可能来自用户输入,来自数据库等).所以我需要一个"宽容"的比较.
常见的解决方案是使用epsilon值进行比较(参见 …
在Hashmap中,提供的密钥的哈希码用于将值放在哈希表中.在Hashset中,obects哈希码用于将值放在底层哈希表中.也就是说,hashmap的优点是你可以灵活地决定你想要什么作为键,这样你就可以做到这样的好事.
Map<String,Player> players = new HashMap<String,Player>();
Run Code Online (Sandbox Code Playgroud)
这可以将诸如玩家名称之类的字符串映射到玩家本身.
我的问题是当密钥的Hashcode发生变化时,查找会发生什么.
我希望这不是Hashmap的主要问题,因为我不希望也不希望密钥发生变化.在前面的例子中,如果球员名称发生变化,他就不再是那个球员了.但是我可以使用密钥更改其他不是名称的字段来查看播放器,将来的查找将起作用.
但是在Hashset中,由于整个对象的哈希码用于放置项目,如果某人略微更改了对象,则该对象的未来查找将不再解析为Hashtable中的相同位置,因为它依赖于整个对象Hashcode.这是否意味着一旦数据在Hashset中就不应该被更改.还是需要重新加入?还是自动完成等?到底是怎么回事?
我对JPA和Hibernate都很陌生(虽然我正在努力学习!)我正在努力解决一个我似乎无法找到一个简单解决方案的问题,所以现在就是这样.
我有一个看起来像下面这样的实体:
@Entity
@Table(name = "mytable1")
public class EntityOne {
// surrogate key, database generated
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// business key
@Column(name = "identifier", nullable = false, unique = true)
private String identifier;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "twoId", nullable = false)
private EntityTwo two;
@OneToMany(mappedBy = "entityOne", fetch = FetchType.EAGER,
cascade = {CascadeType.ALL}, orphanRemoval = true)
private Set<EntityThree> resources = new HashSet<>();
// getters/setters omitted
@Override
public int hashCode() …Run Code Online (Sandbox Code Playgroud) 我希望将不同长度的字符串(通常为1-100个字符)编码为整数,使得字典相似的字符串(它们将在字典中靠近在一起)产生紧密相连的整数,同时进一步确保这些整数在可能的整数值范围内合理均匀分布.
我认识到确保均匀分布可能需要在编码之前对可能的字符串进行某种调查.
有没有人对如何做到这一点有任何想法?
我发现我的自我重写Equals()并GetHashCode()经常实现具有相同属性值的业务对象相等的语义.这会导致代码重复写入并且易于维护(属性被添加,并且一个/两个覆盖都不会更新).
代码最终看起来像这样(欢迎对实现的评论):
public override bool Equals(object obj)
{
if (object.ReferenceEquals(this, obj)) return true;
MyDerived other = obj as MyDerived;
if (other == null) return false;
bool baseEquals = base.Equals((MyBase)other);
return (baseEquals &&
this.MyIntProp == other.MyIntProp &&
this.MyStringProp == other.MyStringProp &&
this.MyCollectionProp.IsEquivalentTo(other.MyCollectionProp) && // See http://stackoverflow.com/a/9658866/141172
this.MyContainedClass.Equals(other.MyContainedClass));
}
public override int GetHashCode()
{
int hashOfMyCollectionProp = 0;
// http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
// BUT... is it worth the extra math given that elem.GetHashCode() should be well-distributed?
int bitSpreader = 31; …Run Code Online (Sandbox Code Playgroud) 我有以下用作图表一部分的类:
public class MyNode {
private String name;
private Set<MyNode> parents;
private Set<MyNode> children;
// getters and setters
}
Run Code Online (Sandbox Code Playgroud)
当我使用Eclipse时Source / Generate hashCode() and equals(),它会生成以下方法:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((children == null) ? 0 : children.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((parents == null) ? 0 : parents.hashCode()); …Run Code Online (Sandbox Code Playgroud) 我想知道,如何有效地计算hashCode类似BitSet的实现Set<Integer>.
该BitSet#hashCode显然是快速地计算,而愚蠢的(*)和不兼容的Set#hashCode().
快速兼容的实现可能会像
int hashCode() {
int result = 0;
for (int i=0; i<bits.length; ++i) {
long word = bits[i];
result += 64 * i * Long.bitCount(word) + weightedBitCount(word);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果有一个有效的实施
int weightedBitCount(long word) { // naive implementation
int result = 0;
for (int i=0; i<64; ++i) {
if ((word & (1L << i)) != 0) {
result += i;
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果未设置大多数位,可以通过测试word==0 …