2016-09-26 1 views
2

Javaのに考えるからいくつかのコードがあります:このHashMap実装でこのような操作を使用するポイントは何ですか?

public class SimpleHashMap<K,V> extends AbstractMap<K,V> { 
    static final int SIZE = 997; 
    @SuppressWarnings("unchecked") 
    LinkedList<MapEntry<K,V>>[] buckets = new LinkedList[SIZE]; 
    public V put(K key, V value) { 
     V oldValue = null; 
     int index = Math.abs(key.hashCode()) % SIZE; 
     if(buckets[index] == null) 
      buckets[index] = new LinkedList<MapEntry<K,V>>(); 
     LinkedList<MapEntry<K,V>> bucket = buckets[index]; 
     // ... 
    } 
    // ... 
} 

int index = Math.abs(key.hashCode()) % SIZE;文字列のポイントは何ですか?正確に絶対値とモジュラス演算を使用するのはなぜですか?

+0

正のサイズの範囲内の新しい要素のインデックスを作成する必要があります。そのため、%サイズ – Marcin

答えて

2

indexは配列インデックスとして使用されることに注意してください。したがって、返される値が負の数であるか、または正の数がSIZE-1より大きい可能性があるため、「生の」ハッシュコードを使用することはできません。

  • 絶対値数はモジュロインデックスが許可配列インデックスの範囲にあることを確認するために使用される
  • 非負であることを保証するために使用されます。

もちろん、インデックスが範囲内にあることを保証する他の方法を開発することができます。たとえば、最初にモジュロを計算してから、負の数にSIZEを追加することができます。

+0

残念ながら、これは悪い例です。 'Math.abs(Integer.MIN_VALUE) 'が' MIN_VALUE'なので、 'index'は' -483'になり、コードがクラッシュします。モジュラス演算の後に 'abs()' *を実行するか、 'SIZE'を追加することを提案します。 *(たぶん彼らは本を「Javaで考えていない」に改名するべきだ)* ;-) – Andreas

2

この式は、固定サイズの配列のインデックスを計算しています。

インデックスは、負でなく、配列の長さより小さくなければなりません。

int index = Math.abs(key.hashCode()) % SIZE; 
hashCode()

方法は、その絶対値が配列の長さを超えて負の値とを返すことができます。したがって、このコードは絶対値を取り、モジュラス演算子を使用して、配列内の位置に余分に大きな値をラップします。

たとえば、hashCode()の値を-1000とします。 Math.abs()からの絶対値は1000です。次に、1000%SIZE(SIZEは997)を取ると3になります。インデックスは3になり、ゼロベースの配列の4番目のバケットを指しています。

+0

が残っています。残念ながら、 'Math.abs(Integer.MIN_VALUE)'は 'MIN_VALUE 'のため、' index'は '-483'になり、コードがクラッシュします。 modulus演算の後に 'abs()' * *を実行すると動作します。 – Andreas

+0

@アンドレアス - 良い点。その場合、上の例は、-1000%SIZEは-3、Math.abs(-3)は3です。 –

関連する問題