2011-07-11 10 views
1

私は非常に頻繁に1つのリストを返す必要があるソフトウェアに取り組んでいます。このリストは、他の多くのリストの最初の(N個までの)要素から構成されています。リターンはクライアントによって変更されません。読み取り専用です。 Iドンとして複数のサブリストにわたるビューである実装をリストしますか?

List ret = new ArrayList<String>(); 
for (List aList : lists) { 
    // add the first N elements, if they exist 
    ret.addAll(aList.subList(0, Math.min(aList.size(), MAXMATCHESPERLIST))); 
    if (ret.size() >= MAXMATCHESTOTAL) { 
     break; 
    } 
} 
return ret; 

私は新しいリストの作成とのaddAll(の使用を避けるしたいと思います):

現在、私は(読みやすくするために簡略化されたコード)の線に沿って何かをやっています新しいリストを返す必要がなく、毎秒何千もの要素を扱っています。この方法は、私のアプリケーションの大きなボトルネックです。

私が探しているのは、含まれている各リストのsubList()結果(安価なビューであり、実際のコピーではない)で構成されているListの実装です。

私はjava.util、Commons Collections、Commons Langなどの通常の容疑者を見てきましたが、私の人生ではそのような実装を見つけることはできません。私はそれがある時点で実装されていなければならないと確信していますし、うまくいけば私は明らかな何かを逃した。

だから私はあなたに目を向ける、スタックオーバーフロー - そのような実装を知っている人は誰ですか?私は自分自身を書くことができますが、ホイールが外に出ればホイールを再発明するのは嫌です。

代わりの効率的なアプローチの提案は大歓迎です!

オプションの背景の詳細​​(私の質問に関連するすべてではないかもしれませんが、私がしようとしていることを理解するのに役立ちます):これはクロスワードスタイルのグリッドにテーマの周りを回る。各テーマは、テーマの関連性の高い順に並べられた任意の数の候補単語リストを有することができる。例えば、「映画」のテーマは、映画のタイトルのリスト、次に俳優のリスト、映画関連の可能性があるまたはそうでない可能性のある場所の一般的なリスト、次いで英語の一般的なリストから始めることができる。リストはそれぞれ、ワイルドカード付きトライ構造に格納されており、グリッド制約を満たす高速検索が可能です(たとえば、 "CAT"はキー "CAT"、 "CA?"、 "C ??" "?AT"、... "???"など)リストは、数語から数万語までさまざまです。任意のクエリについて、例えば、。 "C ??"、ソースリストと同じ順序で並べられたN個(50語)の一致する単語を含むリストを返したいとします。リスト1に「C ??」の3つの一致が含まれている場合、リスト2には7が含まれ、リスト3には100が含まれています。リスト1の3つの一致を最初に含む戻りリストが必要です。そして、私は返された "結合リストビュー"操作が、subList()の実装と同様の方法でaddAll()を継続的に呼び出すよりも効率的であることを望みます。

返されたリストをキャッシュすることは、メモリの制約のためにオプションではありません。私のトライは、すでに(32ビットの)最大サイズのヒープの大部分を消費しています。

PSこれは宿題ではなく、実際のプロジェクト用です。どんな助けも大変ありがとう!

+0

質問は宿題のノートブックからコピー貼り付けされているようです。 –

+0

@saugok - 私はそれは知っていますが、私を信じています。私は15年前に大学を卒業しました。ジャーナルのためのニューヨークタイムズスタイルのクロスワードパズルをテーマにしたプロジェクトを作成するプロジェクトです。私のソフトウェアは動作していますが、それはできるだけ遅いです。 – jkraybill

答えて

1

結果リストにランダムアクセスが必要ですか?または、クライアントコードは結果に対してのみ反復処理を行いますか?

結果を反復処理する必要がある場合のみ。元のリストのリストを持つカスタムリストインプリメンテーションをインスタンスフィールドとして作成します。すべてのリストからアイテムを1つずつ取り出し、そのリストにアイテムがなくなるか、MAXMATCHESTOTALアイテムを返すカスタムイテレータを返します。

ランダムアクセスでも同じことができます。

+0

ええ、それはおそらく、 shelf "結合されたサブリスト"実装。まだ検索しています:) – jkraybill

1
  1. list.addAll()を複数回使用します。シンプルで、外部ジャーを必要とせず、効果がありません。
  2. ジャカルタのコレクションフレームワークにそのようなリストがあります。それは効果的ですが、外部の瓶が必要であり、ジェネリックをサポートしていません。
  3. GoogleからGuavaを確認してください。私はそれがあなたが探しているものを持っていると思う。
+0

私はコモンズコレクションとグアバの両方を見て、何も見当たりませんでした。何か不足していますか? – jkraybill

1

サブリストを返すと何が問題になりますか?つまり、です。サブリストはコピーではありませんが、バッキングアレイへの参照が使用されており、クライアントは読み取り専用であるため、完璧なようです。

EDIT:あなたは大きな塊を作るために、いくつかのリストの内容までグループ化したい理由
は、私は理解していますが、そのような大きな塊を必要としないためにあなたのクライアントを変更できますか?私の他の答えBlockingQueueとプロデューサー/消費者のアプローチを参照してください。

+0

結果のリストには、すべての基本リストからのMAXMATCHESPERLISTと、合計でMAXMATCHESTOTAL個のアイテムのみが含まれている必要があります。 –

+0

denis.solonenkoは正しいです。 1つの(またはしばしば)すべての候補リストの結果で構成される返されたリストが必要です。 – jkraybill

+0

私はあなたが欲しいものを手に入れていると思うし、自分自身のサブリストはそれをしないだろうと思う - 私の他の提案を参照してくださいBlockingQueue – Bohemian

0

BlockingQueueを使用し、消費者がチャンク(リスト)でアイテムを取得するのではなく、必要に応じてキューからアイテムを1つずつ取り出すことを考えましたか?ここでは、プロデューサー/消費者パターンを再考しようとしているようです。

+0

私はアプローチを理解していますが、クライアントの多くは、返されるN個のアイテムのほとんどまたはすべてを繰り返してしまうため、必要なものを得る方法がわからない。私はそれについて考えるつもりですが、私は自分のイテレーターを何らかの形で巻く必要があるという結論に至ります。 – jkraybill

関連する問題