我有一个非常简单的类,只有一个字段成员(例如String).是否可以hashCode()简单地返回fieldMember.hashCode()?或者我应该以某种方式操纵字段的哈希码?另外,如果我应该操纵它,为什么呢?
假设我有以下课程:
class ABC {
private int myInt = 1;
private double myDouble = 2;
private String myString = "123";
private SomeRandomClass1 myRandomClass1 = new ...
private SomeRandomClass2 myRandomClass2 = new ...
//pseudo code
public int myHashCode() {
return 37 *
myInt.hashcode() *
myDouble.hashCode() *
... *
myRandomClass.hashcode()
}
}
Run Code Online (Sandbox Code Playgroud)
这是hashCode的正确实现吗?这不是我通常这样做的方式(我倾向于遵循Effective Java的指导方针),但我总是有诱惑去做类似上面代码的事情.
谢谢
我知道这已经在这里一遍又一遍地讨论,但我尝试过的所有例子都没有为我工作.
我得到了什么
我从Android访问呼叫日志,我得到了所有呼叫的列表.当然,在这里我得到了很多重复.首先我制作一份清单
List<ContactObject> lstContacts = new ArrayList<ContactObject>();
Run Code Online (Sandbox Code Playgroud)
然后我在其中添加对象
While (get some record in call log)
{
ContactObject contact = new ContactObject();
contact.SetAllProperties(......)
lstContacts.add(contact);
}
Set<ContactObject> unique = new LinkedHashSet<ContactObject>(lstContacts);
lstContacts = new ArrayList<ContactObject>(unique);
Run Code Online (Sandbox Code Playgroud)
Contact Object类很简单
public class ContactObject {
public ContactObject() {
super();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ContactObject))
return false;
return this.lstPhones == ((ContactObject) obj).getLstPhones();
}
@Override
public int hashCode() {
return lstPhones.hashCode();
}
private long Id;
private String name;
private List<String> lstPhones; …Run Code Online (Sandbox Code Playgroud) 如果你从db加载一个实体并以某种方式修改它,hibernate会使用equals/hashCode来比较实体的当前状态和它的快照,以确定是否需要执行sql更新?
如果它做了这样的比较,我还有另外一个问题:如果equals将返回true,那么hibernate是否会认为实体没有改变或试图使用它的默认comprasion(可以肯定)?
我希望将不同长度的字符串(通常为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) 我目前有一个被覆盖的equals(Object)看起来像这样:
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (! (o instanceof Player)) return false;
Player p = (Player) o;
return getFirstName().equalsIgnoreCase(p.getFirstName()) &&
getLastName().equalsIgnoreCase(p.getLastName());
}
Run Code Online (Sandbox Code Playgroud)
我hashCode()目前看起来像这样:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + getFirstName().toLowerCase().hashCode();
result = 31 * result + getLastName().toLowerCase().hashCode();
return result;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是关于我重写的hashCode()方法.我知道我需要hashCode()为两个对象返回相同的值,如果它们被equals(Object)方法认为是相等的.我的直觉告诉我,有些情况下这个hashCode()会违反合同.
是否有一种可接受的方法在重写的equals(Object)方法中使用equalsIgnoreCase(String)方法并生成不违反合同的哈希码?
考虑我有一个POJO具有String类成员:
class POJO {
String name, address, emailId;
equals() {
}
hashCode() {
// How?
}
}
Run Code Online (Sandbox Code Playgroud)
如何将hashCode我的弦乐组合成一个hashCodePOJO?
我有以下用作图表一部分的类:
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 …