Java中的IEqualityComparer接口

Java中的IEqualityComparer接口,java,collections,Java,Collections,更具体地说,我需要一个接口来比较只能比较相等的对象[例如,复数],但没有它们的总顺序。 它应该有[注意,它只返回一个布尔值yes/no] boolean Equals(T object1, T object2); 和一个hashcode函数。因此,当我使用对象(比如说收集“相等”的对象)将它们分配到bucket中时,两个“相等”的对象不会出现在两个不同的bucket中 int getHashCode(T object); Java有吗?我找了又找不到 我试图在Hadoop Map Reduc

更具体地说,我需要一个接口来比较只能比较相等的对象[例如,复数],但没有它们的总顺序。 它应该有[注意,它只返回一个布尔值yes/no]

boolean Equals(T object1, T object2);
和一个hashcode函数。因此,当我使用对象(比如说收集“相等”的对象)将它们分配到bucket中时,两个“相等”的对象不会出现在两个不同的bucket中

int getHashCode(T object);
Java有吗?我找了又找不到

我试图在Hadoop Map Reduce中使用它来将“equal”对象分布到同一个Reduce作业中,以便可以对所有“equal”对象进行操作。我只关心对象是否相等,不需要总的顺序。但如果两个对象相等,它们应该具有相同的哈希代码。否则,他们将面临两种不同的工作


请注意,我知道对象的equals和hashcode。但我需要一个外部比较器,它只依赖于对象的一部分。因此对象的相等概念与我的不同。

Java中没有用于此的内置类型。依我看,这是集合设计中的一个“漏洞”。恐怕有一个字符串特定的类,它已经接近极限了

没有办法定制内置的地图来使用特定类型的平等比较,更糟糕的是。想要这个功能是完全合理的,但真正的痛苦是它还没有出现


当然,您可以创建自己的此类接口,并编写自己的地图变体来使用它。。。但是必须这样做很糟糕:(

我建议使用基于函数的方法来生成bucket,就像(现在的番石榴)一样。他们使用
函数
,它将
V
类型的对象映射到
K
类型的键(在你的例子中是bucket)。

最后,我选择写我在类似情况下所做的事情。 如果我需要特殊的等式/散列,比如保持弱引用。你可以这样包装键。总体而言,这与接口方法没有太大区别,但它会创建哑实例(如bucket条目的HashMap/Hashtable)。你可能需要对keySet()进行额外的展开,等等

package t1;

public abstract class KeyX<Key> implements java.io.Serializable {
    private static final long serialVersionUID = 0l;

    final Key key;
    final int hash;
    protected KeyX(Key key){
        this.key = key;
        this.hash = hashCode(key);
    }

    protected abstract int hashCode(Key key);

    //Key, Key will be way too strict and it'd required, key.getClass().isInstance(y) prior calling
    protected abstract boolean equals(Key x, Object y);

    @Override
    public final boolean equals(Object obj) {
        if (obj==this)
            return true;
        if (!(obj instanceof KeyX)){
            return false;
        }
        final KeyX<?> other = (KeyX<?>) obj;
        return this.key==other.key ||  (hash==other.hash && other.key!=null  && equals(this.key, other.key)); 

    }

    @Override
    public final int hashCode() {
        return hash;
    }

    public final Key unwrap(){
        return key;
    }
}
t1包;
公共抽象类KeyX实现java.io.Serializable{
私有静态最终长serialVersionUID=0l;
最后一键;
最终整数散列;
受保护的密钥X(密钥){
this.key=key;
this.hash=hashCode(key);
}
受保护的抽象int哈希代码(Key);
//Key,Key将过于严格,它是必需的,Key.getClass().isInstance(y)在调用之前
受保护的抽象布尔等于(键x,对象y);
@凌驾
公共最终布尔等于(对象obj){
如果(obj==此)
返回true;
如果(!(键X的obj实例)){
返回false;
}
最终键x其他=(键x)obj;
返回this.key==other.key | |(hash==other.hash&&other.key!=null&&equals(this.key,other.key));
}
@凌驾
公共最终int hashCode(){
返回散列;
}
公开最终密钥展开(){
返回键;
}
}

您想要的类型是Guava的。但是,您可能会失望,因为在Java中,
集合
映射
是根据
对象严格指定的。equals
,您将找不到那些在Guava中使用替代等价物的实现。但是,您可以使用稍微模拟这种行为e> myEquivalence.wrap(myObject)

我不知道C的类比,但是你检查过
Object
类吗?它有
equals()
hashCode()
方法。它基本上是继承的(并且可以重写)在每个类中。或者你可能需要
比较器
?不-我想要一个外部比较器-我有不同的“相等”概念从对象本身的相等性来看。假设我只想比较对象的一部分,但对象itslef在所有字段上实现相等。标准java.util不支持类似的功能。我认为
比较器
非常接近。它不返回
布尔值
,但您可以检查它是否返回
0或否。@Balsu-是的-这是我第一次尝试。但不幸的是,comparator没有hashcode。所以我不知道如何将对象分配到Bucket中-因为comparator的相等概念只有它知道,我所做的任何分配都可以将相等的对象扔到不同的Bucket中。有趣的是,Guava为t定义了接口他的,但在它的任何映射实现中都没有使用它。@finnw-这正是我想要的。但我不想仅为该接口使用该库。但知道这一点很好。下次我将使用它,当我已经依赖它时。是的-我最终定义了我自己的EqualityComparator,它是一个完全相同的IEqualityComparer副本,因为我只需要它需要我的map reduce组件和用户之间的合同。对于试图使用HashSet等的人来说,这将是非常痛苦的。IIRC,有一些实现,Google代表“Equalator”。