1

ゲームでは、ユーザーのリストを保持してスコアで並べ替えようとしているので、いつでもリストをクエリして、スコアで上位10人のユーザーを返すことができます。このリストはスレッドセーフである必要があります。userName文字列をキーとして使用することを想定しており、値はComparableを実装し、displayNameやscoreなどのプロパティを持つUserオブジェクトになります。したがって、Userオブジェクトには、スコア属性を比較してその位置を決定するcompareToメソッドがあります。

これにConcurrentSkipListMapを使用することを検討していますが、私が知る限り、Map(Setではなく)はキーを使用して並べ替えます。Userオブジェクトのscoreプロパティでリストを並べ替えたいのですが、特定のユーザーにアクセスしてスレッドからスコア属性を変更できる必要があるため、引き続きMapを使用します。

自分のコンパレータをキーに使用しても問題が解決するようには思えません。比較のために関連する値にアクセスできるとは思えないからです。ConcurrentSkipListSetを使用することもできますが、リストにアクセスして個々のユーザーのスコアを変更すると、(毎回繰り返す必要があるため)コストのかかる操作になります。

誰かがこれを達成する方法を提案することができますか?

4

3 に答える 3

3

いいえ、できません。順序付けに使用されるコンパレータは、インデックス作成に使用されるコンパレータと同じです。おそらく2つのコレクションを維持する必要があります。1つは、ユーザーのスコアの順序を維持するためのもので、ユーザーを名前で参照するためのものです。

于 2010-09-21T18:08:05.010 に答える
1

マイケルは正しいです、あなたはあなたのケーキを持ってそれを食べることもできません;)

私はあなたが3つの選択肢があると思います:

  1. マップを使用して、ユーザーのスコアの更新が迅速に行われるようにします。また、最高のスコアを見つけるために並べ替えるときに料金を支払います。
  2. スコアでソートするSortedSetを使用して、最高のスコアをすばやく見つけることができますが、ユーザーのスコアを更新するときに料金を支払う必要があります
  3. 2つのデータ構造を維持して、1と2のベストを得ることができるようにします。たとえば、スコアでソートされたセット内の実際のデータを持ちながら、セットなどにインデックスを付けるためのユーザー名のマッピングも維持します。そうすれば、常にソートされたスコアが得られ、ユーザーのスコアの更新は単なる検索であり、検索ではありません。これに支払う代償は、2つの場所で重複情報を維持していることです。特に同時アクセスを考慮すると、両方の場所が常に同期して更新されるようにするのは難しい場合があります。

私は1と2の間でどちらが速いかについての仮定をしません。私はあなたの予想される使用法でそれらを試してみて、何が最悪かを見るために測定します。

本当に上位nスコアのみに関心がある場合は、そのリストを個別に維持する可能性があります。したがって、ユーザー名のマップを用意して、全員のスコアを取得するだけでなく、上位スコア(およびそのユーザー)の小さなセットを維持します。誰かのスコアを追加/更新するたびに、スコアを一番上のスコアリストと照合し、そこにある最小のスコアよりも大きい場合は、スコアを追加して下のスコアをバンプします。これは上記の提案3に似ていますが、オーバーヘッドが少なく、おそらく保守が容易です。

于 2010-09-21T19:17:18.333 に答える
1

get(key)コンパレータに依存します(キーを見つけることができるようにするため)。get(key)(キーのマップされた値にアクセスして、それに基づいて比較する)に依存するコンパレータを提案します。それは必然的に無限の再帰とスタックオーバーフローにつながります(明るい面では、あなたは正しいウェブサイトに投稿しています!!)

于 2010-09-21T18:32:10.260 に答える