【发布时间】:2012-01-16 22:01:59
【问题描述】:
我对我们定义了自定义键对象的TreeMap 有疑问。问题是,在将一些对象放入地图并尝试使用用于放置在地图上的相同键进行检索后,我得到一个空值。我相信这是因为我们在密钥上有 2 个数据点。一个值总是被填充,一个值并不总是被填充。因此,问题似乎在于使用compareTo 和equals。不幸的是,我们的密钥如何确定相等性的业务需求需要以这种方式实现。
我认为最好用代码来说明这一点。
public class Key implements Comparable<Key> {
private String sometimesPopulated;
private String alwaysPopulated;
public int compareTo(Key aKey){
if(this.equals(aKey)){
return 0;
}
if(StringUtils.isNotBlank(sometimesPopulated) && StringUtils.isNotBlank(aKey.getSometimesPopulated())){
return sometimesPopulated.compareTo(aKey.getSometimesPopulated());
}
if(StringUtils.isNotBlank(alwaysPopulated) && StringUtils.isNotBlank(aKey.getAlwaysPopulated())){
return alwaysPopulated.compareTo(aKey.getAlwaysPopulated());
}
return 1;
}
public boolean equals(Object aObject){
if (this == aObject) {
return true;
}
final Key aKey = (Key) aObject;
if(StringUtils.isNotBlank(sometimesPopulated) && StringUtils.isNotBlank(aKey.getSometimesPopulated())){
return sometimesPopulated.equals(aKey.getSometimesPopulated());
}
if(StringUtils.isNotBlank(alwaysPopulated) && StringUtils.isNotBlank(aKey.getAlwaysPopulated())){
return alwaysPopulated.equals(aKey.getAlwaysPopulated());
}
return false;
}
因此,当在地图上放置一些项目后尝试从地图上获取值时会出现问题。
Map<Key, String> map = new TreeMap<Key, String>();
Key aKey = new Key(null, "Hello");
map.put(aKey, "world");
//Put some more things on the map...
//they may have a value for sometimesPopulated or not
String value = map.get(aKey); // this = null
那么为什么只是放入后值 null 呢?我认为TreeMap 使用的算法以不一致的方式对地图进行排序,因为我使用compareTo 和equals 的方式。我愿意接受有关如何改进此代码的建议。谢谢
【问题讨论】:
-
你是否彻底测试过 Key.equals() 方法?
-
如果您有多个键且两个字段为空,则会得到一棵混合树。
-
is:
if(StringUtils.isNotBlank(alwaysPopulated) && StringUtils.isNotBlank(aKey.getAlwaysPopulated()))曾经是假的吗? -
您最好在设置字段时验证字段,而不是在每次比较时重新验证。
-
alwaysPopulated 永远不会为空,所以不,它不会超过 if 条件。