diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index b09a275402e1f0b80fd6ede7b778649f818dd292..0a2b010b6bf35ffea2c851c89644a8e103991cfa 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -180,7 +180,7 @@ public class Key {
         mY = y;
         mHitBox.set(x, y, x + width + 1, y + height);
 
-        mHashCode = hashCode(this);
+        mHashCode = computeHashCode(this);
     }
 
     /**
@@ -334,7 +334,7 @@ public class Key {
         mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr,
                 R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase,
                 params.mId);
-        mHashCode = hashCode(this);
+        mHashCode = computeHashCode(this);
 
         keyAttr.recycle();
 
@@ -366,7 +366,7 @@ public class Key {
         }
     }
 
-    private static int hashCode(Key key) {
+    private static int computeHashCode(Key key) {
         return Arrays.hashCode(new Object[] {
                 key.mX,
                 key.mY,
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 6703b93017a1a8055c886a9364095c7dbae6edb1..3b2b11e4e2194a036d2136f8453dc5703a6ed873 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -70,23 +70,23 @@ public class KeyboardId {
     public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
             EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
             boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
-        this.mLocale = locale;
-        this.mOrientation = orientation;
-        this.mWidth = width;
-        this.mMode = mode;
-        this.mElementId = elementId;
-        this.mEditorInfo = editorInfo;
-        this.mClobberSettingsKey = clobberSettingsKey;
-        this.mShortcutKeyEnabled = shortcutKeyEnabled;
-        this.mHasShortcutKey = hasShortcutKey;
-        this.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
-        this.mCustomActionLabel = (editorInfo.actionLabel != null)
+        mLocale = locale;
+        mOrientation = orientation;
+        mWidth = width;
+        mMode = mode;
+        mElementId = elementId;
+        mEditorInfo = editorInfo;
+        mClobberSettingsKey = clobberSettingsKey;
+        mShortcutKeyEnabled = shortcutKeyEnabled;
+        mHasShortcutKey = hasShortcutKey;
+        mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
+        mCustomActionLabel = (editorInfo.actionLabel != null)
                 ? editorInfo.actionLabel.toString() : null;
 
-        this.mHashCode = hashCode(this);
+        mHashCode = computeHashCode(this);
     }
 
-    private static int hashCode(KeyboardId id) {
+    private static int computeHashCode(KeyboardId id) {
         return Arrays.hashCode(new Object[] {
                 id.mOrientation,
                 id.mElementId,
@@ -109,21 +109,21 @@ public class KeyboardId {
     private boolean equals(KeyboardId other) {
         if (other == this)
             return true;
-        return other.mOrientation == this.mOrientation
-                && other.mElementId == this.mElementId
-                && other.mMode == this.mMode
-                && other.mWidth == this.mWidth
-                && other.passwordInput() == this.passwordInput()
-                && other.mClobberSettingsKey == this.mClobberSettingsKey
-                && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
-                && other.mHasShortcutKey == this.mHasShortcutKey
-                && other.mLanguageSwitchKeyEnabled == this.mLanguageSwitchKeyEnabled
-                && other.isMultiLine() == this.isMultiLine()
-                && other.imeAction() == this.imeAction()
-                && TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
-                && other.navigateNext() == this.navigateNext()
-                && other.navigatePrevious() == this.navigatePrevious()
-                && other.mLocale.equals(this.mLocale);
+        return other.mOrientation == mOrientation
+                && other.mElementId == mElementId
+                && other.mMode == mMode
+                && other.mWidth == mWidth
+                && other.passwordInput() == passwordInput()
+                && other.mClobberSettingsKey == mClobberSettingsKey
+                && other.mShortcutKeyEnabled == mShortcutKeyEnabled
+                && other.mHasShortcutKey == mHasShortcutKey
+                && other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled
+                && other.isMultiLine() == isMultiLine()
+                && other.imeAction() == imeAction()
+                && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel)
+                && other.navigateNext() == navigateNext()
+                && other.navigatePrevious() == navigatePrevious()
+                && other.mLocale.equals(mLocale);
     }
 
     public boolean isAlphabetKeyboard() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index e88ab685abd5831b2afbed1abef9f3ec7794e50b..70530c338a8174a2dfbaccb306088be02452c301 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -64,6 +64,19 @@ public class FusionDictionary implements Iterable<Word> {
             mWord = word;
             mFrequency = frequency;
         }
+
+        @Override
+        public int hashCode() {
+            return Arrays.hashCode(new Object[] { mWord, mFrequency });
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) return true;
+            if (!(o instanceof WeightedString)) return false;
+            WeightedString w = (WeightedString)o;
+            return mWord.equals(w.mWord) && mFrequency == w.mFrequency;
+        }
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/makedict/Word.java b/java/src/com/android/inputmethod/latin/makedict/Word.java
index c2c01e1f879b91f8493b1d0b6b4570911adf24b4..776b2aa977d8e5312cb2ab08d19b3db98026fabb 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Word.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Word.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.makedict;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Utility class for a word with a frequency.
@@ -32,6 +33,8 @@ public class Word implements Comparable<Word> {
     final ArrayList<WeightedString> mShortcutTargets;
     final ArrayList<WeightedString> mBigrams;
 
+    private int mHashCode = 0;
+
     public Word(final String word, final int frequency,
             final ArrayList<WeightedString> shortcutTargets,
             final ArrayList<WeightedString> bigrams, final boolean isShortcutOnly) {
@@ -42,6 +45,16 @@ public class Word implements Comparable<Word> {
         mIsShortcutOnly = isShortcutOnly;
     }
 
+    private static int computeHashCode(Word word) {
+        return Arrays.hashCode(new Object[] {
+                word.mWord,
+                word.mFrequency,
+                word.mIsShortcutOnly,
+                word.mShortcutTargets.hashCode(),
+                word.mBigrams.hashCode()
+        });
+    }
+
     /**
      * Three-way comparison.
      *
@@ -63,10 +76,19 @@ public class Word implements Comparable<Word> {
      */
     @Override
     public boolean equals(Object o) {
+        if (o == this) return true;
         if (!(o instanceof Word)) return false;
         Word w = (Word)o;
         return mFrequency == w.mFrequency && mWord.equals(w.mWord)
                 && mShortcutTargets.equals(w.mShortcutTargets)
                 && mBigrams.equals(w.mBigrams);
     }
+
+    @Override
+    public int hashCode() {
+        if (mHashCode == 0) {
+            mHashCode = computeHashCode(this);
+        }
+        return mHashCode;
+    }
 }