2011-06-20 71 views
2

沒有任何運氣發現這一點,但我試圖重寫Java中的字符串函數。我正在使用給定的源代碼進行字典搜索,它如何工作基本上是散列所有單詞。它雖然這樣做,「HI」和「嗨」不是同一個詞。我想最簡單的方法是編寫我自己的字符串散列函數,以便「hi」然後在字典中散列並顯示「Hi」。我該怎麼做呢?覆蓋Java中的字符串哈希函數

+0

重寫String hashCode()將不會受益,除非您也覆蓋equals()。改變兩者都有可能破壞任何使用String的代碼(這是大部分的JDK) –

回答

4

您使用單個字段(字符串)創建類。

你@Override equals和hashCode在你的類上做不區分大小寫的東西。

您將類的對象存儲在HashSet或HashTable中或其他類中。

+0

這將涉及很多代碼重寫示例寫入的方式。有沒有辦法只爲程序單獨使用字符串funcs? – Jdban101

+0

如果您首先重構代碼以刪除與使用地圖有關的所有重複內容,那麼執行此操作只需要更改大約三行代碼:創建地圖,在地圖中放置東西,從地圖中取出東西。 –

2

在運行散列函數之前調用String.toUpperCase()

+0

它的工作方式是,它看到它們是相等的,然後從字典定義的哈希表中獲取字符串。因此,如果我使用String.toUpperCase來使哈希和所有內容相等,我最終會把所有的單詞都寫成大寫 – Jdban101

+0

@ Jdban101 - 如果你希望在你的哈希中不區分大小寫,那麼你必須有多個大小寫。你想要哪一個?他們全部? – dfb

+0

@spinning_plate我希望我的散列在同一個地方搜索「hi」和「HI」,這樣他們就可以從數據庫中取出「Hi」這個詞。這些情況並不是一成不變的,諸如「DSL」之類的字詞就在詞典中,正如「T1 Cable」這樣的詞 – Jdban101

4

類似@奧利的,但不必調用

之前打電話......案例
public class CaseInsensitiveMap<V> implements Map<String, V> { 

    private final Map<String, V> map; 

    public CaseInsensitiveMap(Map<String, V> map) { 
    this.map = map; 
    } 

    public V put(String key, V value) { 
    return map.put(key.toLowerCase(), value); 
    } 

    /// etc... 
} 
+0

這是錯誤的。在Locale.setDefault(新Locale(「tr」))後嘗試「HI」。搜索「臭名昭着的土耳其語區域錯誤」。 –

+0

@bkail我認爲它已經爲拉丁字母設計。如果你將locale設置爲'tr',那麼yes和hı是不區分大小寫的相同的東西,它仍然有效。問題在哪裏? –

+0

put(「HI」,...)是否得到(「hi」)取決於語言環境。一種修復方法是toLowerCase(Locale.ENGLISH)。 –

1

的想法有三個缺點:它是壞的,不可能也沒有必要。

這是不可能的,因爲java.lang.String是最終的。你不能從它繼承,所以你不能覆蓋任何方法。

從兩方面來看,這很糟糕:首先是因爲你會改變其中一個核心類的契約和行爲。能夠傳遞一個不像String的行爲實例可以從字面上打破任何事情。其次,我明白要做你想做的事情,你也必須重寫equals,並且這將以一個不對稱的等式結束(其中a.equals(b)!= b.equals(a) b是一個簡單的字符串和一個你的特殊版本)。我認爲不區分大小寫的字符串等於普通字符串,實際上是Bloch的「Effective Java」中一個非常糟糕的主意的例子。

這是沒有必要的,因爲你需要的是一個持有一個字符串並委託給它的對象。它也可以有一個構造函數或一個靜態工廠方法,它接受一個純字符串。或者不區分大小寫的地圖。其他答案中有很多例子。

+0

不是不可能的。您可以使用Xbootclasspath提供您自己的String類版本。如果代碼不在安全的環境中運行(即JNLP),您甚至可以使用它來重新編寫散列函數,因爲它需要OP。然而,這是非常糟糕的做法,我同意,完全沒有必要。 – hoipolloi

+0

@hoipolloi - 「不可能」在「不可能從外部訪問私有屬性」。精度太高會導致答案失效:-) – fdreger

+0

「無法從課外訪問私人屬性」 - 正確嗎? http://download.oracle.com/javase/1.4.2/docs/api/java/lang/reflect/AccessibleObject.html - > setAccessible ...只是在開玩笑,我知道你的意思。 :) – hoipolloi