2011-01-29 12 views
11

Daha özel olarak, yalnızca eşitlikle karşılaştırılabilecek nesneleri karşılaştırmak için bir arabirim istiyorum [ör. karmaşık sayılar] ama üzerinde toplam sipariş yok. O varIEqualityComparer arabirimi Java'da

boolean Equals(T object1, T object2); 

ve karma kodudur fonksiyonu [sadece hayır/bir boolean evet döndüren unutmayın] olmalıdır. Böylece nesneleri "eşit" nesneleri toplamak için kovalar kullanarak dağıttığımda, 2 "eşit" nesne iki farklı kovada bitmez.

int getHashCode(T object); 

Java var mı? Aradım ve bulamadım.

ben bütün "eşit" nesneler üzerinde çalışabilir, böylece işi azaltmak aynı etmek "eşit" nesneleri dağıtmak için azaltın Hadoop Harita kullanmak çalışıyorum. Sadece nesnelerin eşit olup olmadığına ve toplam siparişe ihtiyaç duymayacağına dikkat ediyorum. Fakat eğer iki nesne eşitse, aynı karma kodu olmalıdır. Aksi takdirde, iki farklı azaltılmış işte sona ereceklerdir.

Ben eşittir ve nesnenin karma kodu hakkında bilmek unutmayınız. Ama bir nesnenin sadece bir kısmına bağlı olduğunu söyleyen bir harici karşılaştırıcı istiyorum. Yani nesnenin eşitlik kavramı benimkinden farklıdır.

+0

C# benzeşimi hakkında hiçbir fikrim yok, ancak 'Object' sınıfını kontrol ettiniz mi? 'Equals()' ve 'hashCode()' yöntemlerine sahiptir. Her sınıfta temel olarak kalıtsal (ve değiştirilemez) bir şeydir. http://download.oracle.com/javase/6/docs/api/java/lang/Object.html Veya belki de 'Karşılaştırıcı'ya ihtiyacınız var mı? http://download.oracle.com/javase/6/docs/api/java/util/Comparator.html – BalusC

+4

Hayır - Harici bir karşılaştırıcı istiyorum - Nesnelerin eşitliğinden farklı olarak "eşitlik" kavramına sahibim.Ben sadece nesnenin bir kısmını karşılaştırmak istediğimi, ancak nesnenin tüm alandaki eşitliğini uygulayacağını söyle. – Fakrudeen

+0

standart java.util, benzer işlevleri desteklememektedir. – bestsss

cevap

10

Java bunun için kullanılan yerleşik bir türü de vardır. Koleksiyon tasarımında bir "delik", IMO. Dize özgü Collator sınıfı var, o kadar yaklaşıyor, korkarım.

eşitlik karşılaştırma belli bir tür, kötü şans kullanmak yerleşik haritalar özelleştirme yolu yok. Bu işlevselliği ve zaten mevcut olmayan gerçek bir acı istiyorsanız tamamen makul var.

Elbette kendi Böyle bir arayüz oluşturmak ve kullanmak kendi harita varyantlarını yazma ... ama bunu yapmak zorunda berbat :(Ben kova oluşturmak için bir fonksiyon temelli yaklaşım kullanarak öneririm

+0

Evet - Kendi Eşitlik Karşılaştırıcısı 'u tanımlamayı bitirdim. Bu, tam anlamıyla bir IEqualityComparer kopyasını belirledim, çünkü yalnızca benim harita azaltma bileşenim ve kullanıcılar arasındaki bu sözleşmeye ihtiyacım var. HashSet vb kullanmaya çalışan biri için çok acı verici olacaktır. – Fakrudeen

+0

IIRC, "Equalator" için Google'da bazı uygulamalar var. – maaartinus

2

olabilir MultiMaps.index() method in Google collections (şimdi Guava) yaptığı gibi. Onlar. Ben benzer durumlarda ne yazmayı tercih sonunda

+2

İlginçtir ki, Guava bunun için [Equivalence ] (http://guava-libraries.googlecode.com/svn/tags/release08/javadoc/com/google/common/base/class-use/Equivalence.html) arayüzünü tanımlar. ancak Map uygulamalarının hiçbirinde kullanmaz. – finnw

+1

@finnw - Tam olarak istediğim bu. Ancak bu kütüphaneyi sadece bu arayüz için kullanmak istemiyorum. Ama bilmek güzel. Bunu bir dahaki sefere kullanacağım, zaten ona bağımlı olduğumda. – Fakrudeen

0

(sizin durumunuzda kovalar içinde) tip K anahtarlarına tip V nesneleri eşleştiren bir Function<V,K> kullanın. Örneğin, zayıf referanslar tutmak gibi özel bir eşitlik/karmaşaya ihtiyacım varsa, anahtarı bu şekilde sarabilirsiniz. y arabirim yaklaşımından farklıdır, ancak aptal örnekler oluşturur (Hash girişleri için HashMap/Hashtable gibi). Sen ...

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; 
    } 
} 
7

Eğer Guava en Equivalence olduğunu istediğiniz tip vb anahtar kümesi() ve ekstra unwrapping gerekebilir. Ancak, Java Collection olduğu gibi hayal kırıklığı olabilir ve Map oldukça katı Object.equals açısından belirtilir ve alternatif bir denklik kullanan Guava bulunanların uygulamaları bulamazsınız. Bununla birlikte, bu davranışı myEquivalence.wrap(myObject) kullanarak biraz benzetebilirsiniz.