我有一个类属性,它有2个变量,如 int a,b ;
我想在两个不同的HashSet中使用class Attribute。
当 a 的值相同时,第一个哈希集会将对象视为相等。 但是当 b 的值相同时,第二个哈希集会将对象视为相等。
我知道如果覆盖 等于方法,哈希集将使用equals的覆盖版本来比较两个对象,但在这种情况下我需要两个不同的equals实现()
单向是创建属性的两个子类,并为它们提供不同的equals方法,但我想知道是否有更好的这样做的方式,我不必创建属性的子类。
感谢。
答案 0 :(得分:3)
一种可能的解决方案是不使用HashSet
,而是使用TreeSet
。它是相同的Set
接口,但有一个TreeSet
构造函数可以传入Comparator
。这样你可以保持Attribute
类不变 - 只需创建两个不同的比较器并像
Set<Attribute> setA = new TreeSet<Attribute>(comparatorForA);
Set<Attribute> setB = new TreeSet<Attribute>(comparatorForB);
比较器负责等式检查(例如,如果compare
返回0,则对象相等)
答案 1 :(得分:1)
不幸的是,没有“均衡器”类可以覆盖equals
逻辑。排序有这样的事情,您可以根据Comparable
实现使用自然排序,也可以提供自己的Comparator
。我实际上想知道为什么平等检查没有这样的东西。
由于相等的语义是由类定义的,并且可以被认为是该类的特征,因此两个子类方法似乎是最自然的。也许有人知道以一种更简单的方式做到这一点的有用模式,但我从未遇到过它。
编辑:只是想到了某些事情......您可以使用两个Map
个实例,例如HashMap
,第一个使用a
作为关键,第二个使用b
作为关键。它可以让你检测到碰撞。然后,您可以将该属性链接到关联的实例。
答案 2 :(得分:1)
我做了一些不同的事情,反而使用 HashSet ,我有使用 HashMap 我在哪里在第一个HashMap中使用 int a 作为键,对象存储为value。 在另一个 HashMap 中,我将键保存为 int b ,将对象保留为值。
这为我提供了对变量 a 和 b 进行哈希处理的方法,因此我不必创建任何子类。
而且,我得到O(1)时间而不是O(log n)。但是我知道我通过使用更多内存来付出代价,但我主要担心的是时间,所以我在TreeSet上选择了HashMap。
感谢大家的意见和建议。
答案 3 :(得分:0)
修改HashMap
和HashSet
以接受散列和相等测试策略非常容易。
public interface Hasher {
int hashCode(Object o);
}
public interface Equalizer {
int areEqual(Object o1, Object o2);
}
答案 4 :(得分:0)
一个简单的解决方案是绕过HashSet
并直接使用HashMap
。首先,使用Attribute
属性作为关键字存储每个a
,将另一个b
存储为{{1}}。
答案 5 :(得分:0)
我可以提出一点hacky但是努力程度较低的解决方案:) 当存储在第二个散列集中时,交换a和b的值,以便通过b的值定义唯一性,然后在从hashset读取类时,再次交换a和b的值以保留原始状态。所以相同的equals / hascode方法将达到目的。