2016-09-11 8 views
2

Wie kann ich mehrere Streams in einen Stream konvertieren? Zum Beispiel habe ich 3 IntStreams und ich möchte sie zu einem Stream von int-Arrays kombinieren.Erstellen eines Streams durch Kombinieren des Ergebnisses mehrerer Streams

Im Javadoc nehmen die meisten Stream-Operationen einen Stream als Eingabe, und die concat beantwortet meinen Anwendungsfall nicht.

Hier ist, was ich im Sinn hatte

Stream 1: 1, 2, 3 
Stream 2: 4, 5, 6 
Combined Stream ex1: [1,4],[2,5],[3,6] 
Combined Stream ex2: 1+4,2+5,3+6 
Combined Stream ex3: new MyObject(1,4), new MyObject(2,5), new MyObject(3,6) 
+2

Das ist ähnlich zu dieser Frage in Geist http://stackoverflow.com/questions/37702703/is-it-possible-to-flatmap-or-collect-evenly-multiple-collections – Tunaki

+0

mm, ich las Ihre Antwort, und du sprichst von Interleaving, das Concat ähnlich ist. Ich werde mein Beispiel ändern, um zu klären, –

+1

Ah, ich sehe, Sie möchten [zip die Streams] (http://stackoverflow.com/questions/17640754/ziping-streams-using-jdk8-with-lambda-java-util -stream-streams-zip) mit einer benutzerdefinierten Reißverschlussfunktion. – Tunaki

Antwort

2

Funktional, sich das Problem auf eine Liste von Streams zu zippen, und eine Anwendung individueller Reißverschluss für jedes Element.

There is no facility, um dies direkt mit der Stream-API zu tun. Wir können Bibliotheken von Drittanbietern verwenden, wie zum Beispiel die protonpack-Bibliothek, die dafür eine zip-Methode bereitstellt. Unter Berücksichtigung der Daten:

List<Stream<Integer>> streams = Arrays.asList(Stream.of(1,2,3), Stream.of(4,5,6)); 

Sie

Stream<Integer> stream = StreamUtils.zip(streams, l -> l.stream().mapToInt(i -> i).sum()); 
// the Stream is now "1+4,2+5,3+6" 

oder

Stream<Integer[]> stream = StreamUtils.zip(streams, l -> l.toArray(new Integer[l.size()])); 
// the Stream is now "[1,4][2,5][3,6]" 

Der Mapper zip nimmt die Liste der Elemente und gibt den Reißverschluss Wert. Im ersten Beispiel wird der Wert zusammen addiert, während im zweiten Beispiel ein Array zurückgegeben wird.

2

Leider gibt es nichts stammt aus dem Stream, die dies für Sie tut. Ein unglücklicher Mangel an der API.

Das heißt, Sie könnten dies tun, indem eine Iterator der Ströme auf jeder Entnahme ähnlich:

public static <T,U,R> Stream<R> zipStreams (Stream<T> a, Stream<U> b, BiFunction<T,U,R> zipFunc) { 
    Iterator<T> itA = a.iterator(); 
    Iterator<U> itB = b.iterator(); 
    Iterator<R> itRet = new Iterator<R>() { 

     @Override 
     public boolean hasNext() { 
      return itA.hasNext() && itB.hasNext(); 
     } 

     @Override 
     public R next() { 
      return zipFunc.apply(itA.next(), itB.next()); 
     } 

    }; 
    Iterable<R> ret =() -> itRet; 
    return StreamSupport.stream(ret.spliterator(), a.isParallel() || b.isParallel()); 
} 
Verwandte Themen