2017-04-10 11 views
3

私は多数の要素を持つリストを持っています。このリストを処理しているときに、リストをより小さなサブリストに分割したい場合があり、場合によってはリスト全体を処理したいことがあります。Java:処理のためにListのチャンクを作成する

private void processList(List<X> entireList, int partitionSize) 
{ 
    Iterator<X> entireListIterator = entireList.iterator(); 
    Iterator<List<X>> chunkOfEntireList = Iterators.partition(entireListIterator, partitionSize); 
    while (chunkOfEntireList.hasNext()) { 
     doSomething(chunkOfEntireList.next()); 
     if (chunkOfEntireList.hasNext()) { 
      doSomethingOnlyIfTheresMore(); 
     } 
    } 

私は、パーティションを作成するためにcom.google.common.collect.Iteratorsを使用しています。だから私はサイズ100でリストを分割したい場合はドキュメントhere のリンクは、私は、リストのチャンクを作成したくないとき、私は整数を渡すと考えていた、今

processList(entireList, 100); 

を呼び出します。 partitionSizeとしてMAX_VALUE

processList(entireList, Integer.MAX_VALUE); 

しかし、これによりコードがメモリ不足になります。誰かが私を助けることができますか?私は何が欠けていますか?イテレータは内部的に何をしていますか?これをどのように克服できますか?

EDIT:さらに処理するリストがある場合にのみ、何かを行うには「if」節が必要です。つまり、iteratorのhasNext()関数が必要です。

答えて

6

Iterators.partition()は、指定されたパーティションの長さの配列を内部的に取り込むため、メモリ不足エラーが発生しています。割り振られた配列は、反復が完了するまで要素の実際の数が分からないため、常にパーティションサイズです。 (彼らは内部的にArrayList使用した場合の問題を防止されている可能性が、私はデザイナーが配列の一般的なケースでは、より良い性能を提供することを決めたと思います。)

がある、List.subList()に委譲するので、問題を回避しますLists.partition()を使用します根底にあるリストの唯一のビュー

private void processList(List<X> entireList, int partitionSize) { 
    for (List<X> chunk : Lists.partition(entireList, partitionSize)) { 
     doSomething(chunk); 
    } 
} 
0

通常、パーティショニング時には、指定されたpartitionSizeで新しいリストを割り当てます。この場合、このようなエラーが発生することは明らかです。なぜあなたは単一のパーティションだけが必要なときに元のリストを使用しないのですか?可能な解決策。

  1. サイズを取らない別のオーバーロードされたメソッドを作成します。
  2. パーティションを必要としない場合は、サイズを-1として渡します。このメソッドでは値をチェックし、-1の場合は元のリストをchunkOfEntireListに入れます。
+0

私はこれを行うと考えました。しかし、それは私の場合にはコードが非常に醜いものにします。 Iterators.partition()とは別の方法で試すことができる代替ソリューションがありますか? –

+0

あなたはpartiotionメソッドを作成することができます..そのメソッドでは、2つの提案されたソリューションのいずれかを実装することができます。それはコードを醜いものにしません – stinepike

0

あなたが並行してあなたのリストのチャンクを処理することによって、並列処理を解決しようとしていると仮定すると、それは良いかもしれない、より大きな枠組みとしてMapReduceのようなもの、またはスパークを検討しますプロセス管理を含む。

しかし、モノリシックアプリケーションの一部として、おそらくJava 8 Streamsを含むノードローカルのバリエーションを考慮することができます。 List<X>でも利用可能なparallelStream()メソッドに注意してください。

関連する問題