2015-11-30 26 views
5

Etkili Java, Madde 8 üzerinde çalışıyorum (Eşitliği geçersiz kılarken genel sözleşmeye uyun). Yazar tarafından oldukça açık bir şekilde açıklanmıştır, ancak yine de bazı kısımlar çok fazla detaylandırılmamıştır. Bu örnek için Kanonik form alanı

, o olarak tanımlanan bir sınıf CaseInsensitiveString dikkate alır: Makalenin sonunda

public final class CaseInsensitiveString { 
    private final String s; 

    public CaseInsensitiveString(String s) { 
     if (s == null) 
      throw new NullPointerException(); 
     this.s = s; 
    } 

    // Broken - violates symmetry! 
    @Override 
    public boolean equals(Object o) { 
     if (o instanceof CaseInsensitiveString) 
      return s.equalsIgnoreCase(((CaseInsensitiveString) o).s); 
     if (o instanceof String) // One-way interoperability! 
      return s.equalsIgnoreCase((String) o); 
     return false; 
    } 
    // ... // Remainder omitted 
} 

, diyor: Böyle CaseInsensitiveString yukarıda, saha karşılaştırmalar gibi bazı sınıfları için

, basit eşitlik testlerinden daha karmaşıktır. Bu durumda, alanın kurallı bir formunu saklamak için isteyebilirsiniz, bu yüzden eşittir yöntemi, daha pahalı olmayan karşılaştırmalı karşılaştırma- isons yerine bu kanonik formlarda ucuz tam olarak karşılaştırmalar yapabilirsiniz. Bu teknik, değişmez sınıflar için en uygun olanıdır (Madde 15); nesnesi değişebilirse, kanonik formu güncel tutmalısınız.

Bu terimi aradım ve temel olarak bir dizindeki bir dosya için sembolik bağlar olmadan mutlak yol gibi bir şeyin standart temsilini ifade ettim. Ancak, bu sınıfa yardım edecek 'kanonik' formun kullanımını anlayamıyorum. Baska öneri?

cevap

5

Bu örnekte, kanonik bir formun String'in küçük harfli veya büyük harfli sürümünü saklayıp bunu karşılaştırarak yapabileceğini düşünüyorum. bunun yerine oldukça kolay daha pahalı equalsIgnoreCase

// Broken - violates symmetry! 
@Override 
public boolean equals(Object o) { 
    if (o instanceof CaseInsensitiveString) 
     return s.equals(((CaseInsensitiveString) o).s); 
    if (o instanceof String) // One-way interoperability! 
     return s.equals((String) o); 
    return false; 
} 
+0

teşekkür, tam dize karşılaştırmaları yapabilir çünkü

private final String s; public CaseInsensitiveString(String s) { //for real code probably use locale version this.s = s.toLowerCase(); } 

Bu eşitlik karşılaştırması ucuz hale getirir. Bunu anladım. Kabul edilmiş! –

İlgili konular