比较通过 id 相等的对象的属性
Comparing properties of objects that equal through an id
假设有一个数据服务 returns class cat
:
的实例
class Cat {
int id;
String name;
int iq;
}
我想将实例保存在 Set<Cat>
中,该实例不能保存两只具有相同 ID 的猫。所以我需要覆盖 equals
和 hashcode
方法来只检查 id
.
我的问题是,当我从服务收到具有相同 ID 但不同值 name
and/or [ 的新实例时,如何检测我的集合中的猫是否需要更新=18=]?我无法将属性添加到 equals
或 hashcode
,因为那时 Set 可能包含相同 ID 的实例。
我是否必须手动比较所有字段,或者是否有其他 Java-典型的解决方案?
编辑澄清:
仅用新实例更新 Set
是不够的,因为更新时触发了代码。所以我想做的是:
if (set.contains(newCat)) {
Cat current = set.get(newCat);
if (!current.equals(newCat)) { //obviously this is not enough
set.add(current);
//notify EventBusses and such
}
}
我想到的解决方案是:
current.requiresUpdate(newCat) //basically copy of equals() with properties
current.updateWith(newCat) //same as above but keeping the old instance
if (!current.name.euqals(newCat.name)) //for each property
- 仅从服务中获取已更改的对象。最佳,但超出我的范围。
所有这些都需要一些冗余代码,这就是为什么我希望有一个模式或集合可以为我完成工作。
解决方案可以包括 Guava classes.
您只需重新输入值即可。
如果 id 与之前的 cat 对象匹配,它将在集合中被覆盖。
一个HashSet内部维护一个HashMap来识别重复项。
更简单的解决方案是:如果发现相等 - 删除它并使用更新后的值再次添加。代码可能有点像这样:
yourSet.remove(cat);
yourSet.add(newCatObejectWithSameID);
newCatObejectWithSameID
会有不同的 name
和 iq
.
您的要求听起来有点奇怪 - 如果 ID 字段应该唯一标识一个 Cat
,那么肯定永远只有一个具有该 ID 的 Cat
实例。或者,至少,多个 Cat
实例上的相应字段应该相等。
但是,假设 可以 有多个逻辑上不同的 Cat
具有相同 ID 的实例,处理此问题的最简单方法是使用 Map<Integer, Cat>
:
Map<Integer, Cat> cats = new HashMap<>();
for (Cat cat : getAllCats()) {
if (!cats.containsKey(cat.id)) {
cats.put(cat.id, cat);
} else {
// Do whatever - ignore, log a message, throw an exception?
}
}
Collection<Cat> catsWithUniqueIds = cats.values();
我认为你有两个截然不同的问题:
- 比较
Cat
对象:如果两个Cat
对象只有在id
、name
和[=15时才相等=] 相等,而不是相应地实施 equals
方法。
- Maintaining a collection of
Cat
objects: 维护Cat
个对象的集合,其中没有两个对象具有相同的[=13] =],按照已经建议的那样使用 Map<Integer, Cat>
。
您的代码可能类似于:
if (mapOfCats.contains(newCat.id)) {
Cat current = mapOfCats.get(newCat.id);
if (!current.equals(newCat)) {
mapOfCats.put(newCat.id, newCat);
// notify EventBusses and such
}
}
假设有一个数据服务 returns class cat
:
class Cat {
int id;
String name;
int iq;
}
我想将实例保存在 Set<Cat>
中,该实例不能保存两只具有相同 ID 的猫。所以我需要覆盖 equals
和 hashcode
方法来只检查 id
.
我的问题是,当我从服务收到具有相同 ID 但不同值 name
and/or [ 的新实例时,如何检测我的集合中的猫是否需要更新=18=]?我无法将属性添加到 equals
或 hashcode
,因为那时 Set 可能包含相同 ID 的实例。
我是否必须手动比较所有字段,或者是否有其他 Java-典型的解决方案?
编辑澄清:
仅用新实例更新 Set
是不够的,因为更新时触发了代码。所以我想做的是:
if (set.contains(newCat)) {
Cat current = set.get(newCat);
if (!current.equals(newCat)) { //obviously this is not enough
set.add(current);
//notify EventBusses and such
}
}
我想到的解决方案是:
current.requiresUpdate(newCat) //basically copy of equals() with properties
current.updateWith(newCat) //same as above but keeping the old instance
if (!current.name.euqals(newCat.name)) //for each property
- 仅从服务中获取已更改的对象。最佳,但超出我的范围。
所有这些都需要一些冗余代码,这就是为什么我希望有一个模式或集合可以为我完成工作。
解决方案可以包括 Guava classes.
您只需重新输入值即可。
如果 id 与之前的 cat 对象匹配,它将在集合中被覆盖。
一个HashSet内部维护一个HashMap来识别重复项。
更简单的解决方案是:如果发现相等 - 删除它并使用更新后的值再次添加。代码可能有点像这样:
yourSet.remove(cat);
yourSet.add(newCatObejectWithSameID);
newCatObejectWithSameID
会有不同的 name
和 iq
.
您的要求听起来有点奇怪 - 如果 ID 字段应该唯一标识一个 Cat
,那么肯定永远只有一个具有该 ID 的 Cat
实例。或者,至少,多个 Cat
实例上的相应字段应该相等。
但是,假设 可以 有多个逻辑上不同的 Cat
具有相同 ID 的实例,处理此问题的最简单方法是使用 Map<Integer, Cat>
:
Map<Integer, Cat> cats = new HashMap<>();
for (Cat cat : getAllCats()) {
if (!cats.containsKey(cat.id)) {
cats.put(cat.id, cat);
} else {
// Do whatever - ignore, log a message, throw an exception?
}
}
Collection<Cat> catsWithUniqueIds = cats.values();
我认为你有两个截然不同的问题:
- 比较
Cat
对象:如果两个Cat
对象只有在id
、name
和[=15时才相等=] 相等,而不是相应地实施equals
方法。 - Maintaining a collection of
Cat
objects: 维护Cat
个对象的集合,其中没有两个对象具有相同的[=13] =],按照已经建议的那样使用Map<Integer, Cat>
。
您的代码可能类似于:
if (mapOfCats.contains(newCat.id)) {
Cat current = mapOfCats.get(newCat.id);
if (!current.equals(newCat)) {
mapOfCats.put(newCat.id, newCat);
// notify EventBusses and such
}
}