2012-08-27 3 views
6

でのHashMapの明確なメソッドの実装を理解することができませんでした私は、Javaのハッシュマップ、このような明確な方法を、見ました。は、Java

なぜテーブルを使用してクリアしないのですか?

+1

おそらく読みやすくするためです。 –

答えて

4

私は、なぜ新しいタブをクリアするのか分かりません。

これは単なるローカル変数です。

は、私は、次の3つの理由を考えることができます。

  • 可読性、@Bheshグルンによって示唆されているように...それはほとんどここで(IMO)違いはありませんけれども。

  • あるスレッドがclear()を呼び出している間に発生するダメージを緩和する可能性がありますが、2番目のスレッドはテーブルを拡張する可能性のある更新を行います。しかし、それは確かに問題を解決しないので、私はこれが無意味であると却下する傾向があります。

  • パフォーマンスが向上することがあります。例えばローカル変数tabの参照が変更できないことをオプティマイザが認識しているため、配列境界チェックを最適化することができます。

これらのうち、第3の理由がもっともらしいと思います。

(私はtransient修飾子とは何かではないと思います。この場合、修飾子は、読みやすくするためにのみ存在している。HashMapクラスはtransient修飾議論の余地をレンダリングreadObjectwriteObjectを提供します。)

2

tableフィールドがtransientと宣言されている可能性があります。そのため、HashMapオブジェクトの永続状態の一部ではありません。 tableフィールドは、resize()のようなメソッドで置き換えられます。これは同期化されないため、clear()メソッド呼び出し内のすべてのエントリを反復処理するときにtableフィールドをスワップすることができます。最初にtableへの参照を行い、その参照を繰り返した場合、tableフィールドが変更されても、元のtableを繰り返し処理していることが保証されます。

+0

しかし、再び 'HashMap'は「通常」の操作ではスレッドセーフではありません。なぜ' clear() 'でそれが気になるでしょうか? –

+0

@JoachimSauerあるスレッドにエントリを追加すると、別のスレッドが 'clear()'を呼び出した直後に 'resize()'が呼び出されます。これにより、 'clear()'コールが新しい 'table'が作成されている間にすべての古いエントリをnullに設定します。それ以外の場合、最悪の場合、追加したばかりのエントリを除いてすべてのnullのHashMapが終了する可能性があります。 –

+0

スレッドの安全性がどのように優れているか理解しています。しかし、私が言っていることは、 'put'だけではスレッドセーフではないということです(複数のスレッドが呼び出すと、厄介なことが起こる可能性があります)。それでは、なぜ他のメソッドがスレッドセーフなのか気になるのでしょうか? –