use*_*mda 6 java equals hashcode hashset
我正在尝试为我的 覆盖提到的方法HashSet:
Set<MyObject> myObjectSet = new HashSet<MyObject>();
Run Code Online (Sandbox Code Playgroud)
我的对象:
public class MyObject implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
int number;
Map<String,String> myMap;
public MyObject(String name, int number, Map<String,String> myMap) {
this.name = name;
this.number = number;
this.myMap = myMap;
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
如何覆盖 hashcode()、equals() 和 compareTo() 方法?
目前我有以下几点:
public int hashCode () {
return id.hashCode();
}
// override the equals method.
public boolean equals(MyObject s) {
return id.equals(s.id);
}
// override compareTo
public int compareTo(MyObject s) {
return id.compareTo(s.id);
}
Run Code Online (Sandbox Code Playgroud)
我读到通过 id 进行比较是不够的,这是对象是数据库的持久实体(请参阅此处)。
名称和编号在此类型的所有对象中并不是唯一的。
那么我应该如何覆盖它?
我还需要比较里面的 hashMap 吗?
我很迷惑。该对象唯一的独特之处是在生命周期后期填充的地图 myMap。
我如何检查它的相等性?
根据所有回复,我已将方法更改为以下
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MyComplexObj myComplexObj = (MyComplexObj) o;
return myMap != null ? myMap.equals(myComplexObj.myMap) : myComplexObj.myMap == null;
}
@Override
public int hashCode() {
return myMap != null ? myMap.hashCode() : 0;
}
public int compareTo(MyComplexObj o) {
return myMap.compareTo(o.getMyMap()));
}
Run Code Online (Sandbox Code Playgroud)
这在 compareTo 方法中失败,“对于类型 Map,此方法未定义
这里的基本问题是“如何确定两个对象是否彼此相等?”
这是一个针对简单对象的简单问题。然而,即使是稍微复杂一点的物体,它也会变得越来越困难。
正如原始问题中所述:
该对象的唯一独特之处是地图 myMap,它会在生命周期的后期填充。
给定类型的两个实例MyObject,成员变量myMap必须相互比较。这张地图属于Map<String, String>. 我立刻想到几个问题:
每个问题的答案都会因应用程序而异。为了使其适用于一般受众,做出以下假设:
equals()使用、hashCode()、的美妙之compareTo()处在于,一旦hashCode()正确实现,其他功能就可以基于 来定义hashCode()。
考虑到所有这些,我们有以下实现:
@Override
public boolean equals(final Object o)
{
if (o instanceof MyObject)
{
return (0 == this.compareTo(((MyObject) o)));
}
return false;
}
@Override
public int hashCode()
{
return getKeyValuePairs(this.myMap).hashCode();
}
// Return a negative integer, zero, or a positive integer
// if this object is less than, equal to, or greater than the other object
public int compareTo(final MyObject o)
{
return this.hashCode() - o.hashCode();
}
// The Map is flattened into a single String for comparison
private static String getKeyValuePairs(final Map<String, String> m)
{
final StringBuilder kvPairs = new StringBuilder();
final String kvSeparator = "=";
final String liSeparator = "^";
if (null != m)
{
final List<String> keys = new ArrayList<>(m.keySet());
Collections.sort(keys);
for (final String key : keys)
{
final String value = m.get(key);
kvPairs.append(liSeparator);
kvPairs.append(key);
kvPairs.append(kvSeparator);
kvPairs.append(null == value ? "" : value);
}
}
return 0 == kvPairs.length() ? "" : kvPairs.substring(liSeparator.length());
}
Run Code Online (Sandbox Code Playgroud)
所有关键工作都在hashCode(). 对于排序,该compareTo()函数只需要返回一个负数/零/正数——一个简单的hashCode()差异。该equals()函数只需要返回真/假——一个compareTo()等于零的简单检查。
为了进一步阅读,刘易斯·卡罗尔(Lewis Carroll)有一段关于逻辑基础的著名对话,其中涉及平等的基本问题:
https://en.wikipedia.org/wiki/What_the_Tortoise_Said_to_Achilles
而且,即使是简单的语法结构,在《爱丽丝梦游仙境》第 6 章“Pig and Pepper”的开头也有两个“相等”句子的很好的例子:
鱼男仆从腋下掏出一封大信,递给对方,语气庄严地说:“致公爵夫人。女王邀请她玩槌球。” 青蛙男仆用同样严肃的语气重复道:“来自女王。邀请公爵夫人玩槌球。” 然后他们都低下了头,卷发纠缠在一起。
| 归档时间: |
|
| 查看次数: |
4290 次 |
| 最近记录: |