2016-08-17 4 views
1

3つのプロデューサからの文字列を非同期で受け取ったとします。Java - インターリーブされたイテレータ/コレクションを取得する方法

"a1" received from A, 
"a2" received from A, 
"c1" received from C, 
"a3" received from A, 
"b1" received from B, 
"b2" received from B, 

私は文字列を返すために、「インターリーブされた」イテレータを希望:これらのオブジェクトの特定の量は、私は、インターリーブ方法でそれらを反復処理したい受信したら、以下の文字列を受け取った場合、つまり、これまでのところ、私は、各プロデューサの1 List<String>を作成しました、そして私は(3つのリストイテレータと協力して、すべての文字列の上に「反復」だ

List<String> interleavedList = {"a1", "b1", "c1", "a2", "c2", "a3"}, 

:私たちは、以下のリストを反復処理しているかのようにa )。これはうまく動作しますが、私は単純な方法があると思います...文字列を受け取っている間にインターリーブされたリストを直接作成することによって、私はどのCollectionまたはどちらがComparatorを使用するかわかりません...

各プロデューサの1つのリストを作成し、次に3番目のリストを4番目のインターリーブリストにマージすることはあまり興味がありません。おそらく時間効率的ではないでしょう。

+0

効率についてもっと教えていただけますか?例えば。ただし、[CyclicBarrier](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html)を使用すると、プロデューサを遅くすることができます。一方、あなたが言及したようにリストを使用することは、完全に時間効率的です。代わりにメモリを使い果たします。 –

+0

これを達成するには、java.util.Iteratorをサブクラス化することができます。次のhttp://stackoverflow.com/questions/3610261/is-it-possible-to-merge-iterators-in-java –

+0

を参照してください。Java 8を使用している場合は、ストリームでインターリーブ文字列を試しましたか? –

答えて

2

ソートを最初に決定する数字と2番目の文字を並べ替えてリストをソートするように見えます。 Javaにはソートされたリストがありません。リストの性質はソートされていないからです。ただし、カスタムのコンパレータでソートセットを使用することができます。

SortedSet<String> sortedset = new TreeSet<String>(
     new Comparator<String>() { 
      @Override 
      public int compare(String e1, String e2) { 
       int num1 = Integer.parseInt(e1.replaceAll("[^\\d.]", "")); 
       int num2 = Integer.parseInt(e2.replaceAll("[^\\d.]", "")); 
       if (num1 > num2) { 
        return 1; 
       } 
       else if (num1 < num2) { 
        return -1; 
       } 
       else { 
        String let1 = e1.replaceAll("[0-9]", ""); 
        String let2 = e2.replaceAll("[0-9]", ""); 
        return let1.compareTo(let2); 
       } 
      } 
     }); 

あなたはこのセットを反復すると、あなたは、あなたの質問に記述順序を取得します。一つの選択肢は、彼らが到着したプロデューサー、特定のインデックスに基づいてPriorityBlockingQueueにすべてのオブジェクトをダンプするだろう

0

class Message { 
    String data; 
    long index; 
} 

PriorityBlockingQueue<Message> queue = new PriorityBlockingQueue<Message>(
    10, 
    Comparator.comparing(m -> m.index) 
); 

List<String> batch = new ArrayList<>(BATCH_SIZE); 
for (;;) { 
    for (int i = 0; i < BATCH_SIZE; i++) { 
     batch.add(queue.take().data); 
    } 
    handleBatch(batch); 
    batch.clear(); 
} 

注意これは無限のキューを想定しています。キューが無限大でない場合は、最後のバッチを処理するロジックを追加する必要があります。

0

PriorityQueue<String>に文字列を追加して、カスタムComparatorを追加できます。この場合、エレメントは追加すると自動的にソートされます。 ここにはuseful exampleがあります。

関連する問題