2016-04-08 11 views
0

Stok nesneleri, anahtarın String (örn. Apple, Inc. için "AAPL") simge numarası olduğu bir HashMap numaralı belgede saklıyorum. Ne yazık ki, bu Ally Financial Inc (GM1) ve Küresel Ortaklar LP (GLP) karma kodları çarpışan ve birbirlerinin üzerine yazacak gibi geçerli değildir. Örneğin: "GM1".hashCode() == "GLP".hashCode() == büyük sorunlar.Stok senedi sembolleri için daha iyi hashCode işlevi?

Herhangi bir çarpışma garanti edemeyen hisse senedi dizeleri için hashCode var mı?

public Class StockTicker { 
    public String symbol; 

    public StockTicker(String symbol) { this.symbol = symbol; } 

    @Override 
    public int hashCode() { 
     // What goes here? 
    } 
} 

Başarılı cevaplar senedi dize en fazla 5 karakterden gerçeği yararlanabilir ve büyük harf alfa-sayısal hariç olacak "" "BRK.B" içinde olduğu gibi.

+3

, geçersiz kılmak emin de eşittir olun:

İşte o mükemmel karma kodunun yaratan bir uygulama bu. – christopher

+0

Mükemmel bir kod yazmaksızın (eşit olmayan nesneler için çarpışmalar olmadan) hashcode yazmak mümkündür, ancak HashMap'in çarpışmalar altında bile çarpışmaları doğru bir şekilde gerçekleştireceğini biliyorsunuz (çok küçük bir performansda da olsa) Evet? Sadece 'return symbol.hashCode();' kullanmak için yeterince kötü mü? – Mshnik

+0

@Mshnik Bu demek oluyor ki ** değil ** mümkün mü? – Kayaman

cevap

2

Diğer cevaplar ve yorumlarda da belirtildiği gibi, A) Java, eşittir ve hashcode'u kabul edilebilir bir şekilde yazdığınızı varsayarak çarpışmaları doğru bir şekilde ele alacaktır ve B) mükemmel bir hashcode işlevi bile almanıza gerek olmadığını garanti etmemektedir. çarpışmalar olsun.

Bununla birlikte, belirtiminiz için mükemmel bir hashcode işlevi yazmak mümkündür. Endişelenmeniz gereken tam olarak 37 karakter vardır (26 harf, 10 rakam ve .), 64'ten daha azdır. Böylece her karakteri temsil etmek için 6 bit kullanabiliriz. En fazla 5 karakteriniz var, yani kod kodunuz bir int içerisinde en fazla 30 biti alır. Eğer hash kodu geçersiz kılarsanız

public static class Stock{ 
    // The possible characters of a stock - note length is < 64 
    private final static String alphaNumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890."; 

    //Will be 6 for given valid chars, but coding it like this prevents bugs later 
    private final static int shiftAmnt = (int)(Math.log(alphaNumeric.length())/Math.log(2)) + 1; 

    private String stock; 

    public Stock(String s) { 
     stock = s; 
    } 

    @Override 
    public boolean equals(Object o) { 
     return o instanceof Stock && stock.equals(((Stock)o).stock); 
    } 

    @Override 
    public int hashCode() { 
     int code = 0; 
     for (char c : stock.toCharArray()) { 
     code = code << shiftAmnt; 
     code += alphaNumeric.indexOf(c); 
     } 
     return code; 
    } 
    } 
+0

İyi, ama bir karma kodun noktasının "büyük" bir nesneyi alıp küçük, benzersiz bir tanımlayıcıya indirgemesinden ötürü, beş karakterlik bir dizeye sahip olmanın bir anlamı var mı? Bir Java karakteri kabaca 2 baytsa, 5 karakterden 80 biti (kabaca), yani teoride hiç kuşku yok gibi görünüyor. – DavidS

+0

(Bu uygulamayı sadece bir örnek olarak sağladığınızı anlıyorum, kullanımının savunulmasını zorunlu kılmıyor. Sadece karma kodları ve amaçlarını düşünmüştünüz, bu yüzden yukarıdaki soruyu sordum.) – DavidS

+0

Tüm doğru, işte bu yüzden Bu konu hakkında daha önceki yorumumu yükselttim.Boyutu küçültmek için mükemmel bir karma işlev istiyor. – Mshnik

4

Anahtar dizeleriyle ilgili hashCode'un haritanın kendisinde herhangi bir etkisi olduğunu sanmıyorum (anahtar kodu değil, gerçek kod satırı sembol dizesini kullandığınızı; karma kodlar, o zaman evet, sorunlara neden olur). Hızlı bir test yaptım ve bu iyi çalışıyor.

private Map<String, String> stockMap = new HashMap<String, String>(); 

@Test 
public void mapTest() { 
    stockMap.put("GM1", "gm1stock"); 
    stockMap.put("GLP", "glpstock"); 

    assertEquals(2, stockMap.size()); 
} 

gibi Mshnik Java sizin için çarpışmalara idare edecek diyor, bu yüzden size dert etmenize gerek bir şey değil. Özel olarak probleminize neden olan kodun ayrıntılarını verebilir misiniz?