Momenteel hebben we de volgende Stream.concat
in Java 8:
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b);
Het verbaast me waarom er geen versie is die een varargs van Stream<? extends T>
?
Momenteel heb ik code geschreven als:
Stream<Integer> resultStream = Stream.concat(stream1, Stream.concat(stream2, Stream.of(element)))
.filter(x -> x != 0)
.filter(x -> x != 1)
.filter(x -> x != 2);
Als een varargs van deze handtekening beschikbaar was:
public static <T> Stream<T> concat(Stream<? extends T>... streams);
Dan zou ik het veel duidelijker kunnen schrijven als:
Stream<Integer> resultStream = Stream.concat(
stream1,
stream2,
Stream.of(element)
)
.filter(x -> x != 0)
.filter(x -> x != 1)
.filter(x -> x != 2);
Zonder allerlei geneste Stream.concat
-aanroepen.
Of zijn er andere redenen waarom het niet wordt verstrekt?
Ik kan zulke redenen niet bedenken, omdat we nu toch het werk van een varargs-oproep doen.
Antwoord 1, autoriteit 100%
Gewoon flatMap
it:
public static void main(final String[] args) throws Exception {
final Stream<String> stream1 = /*some stream*/
final Stream<String> stream2 = /*some stream*/
final Stream<String> stream3 = /*some stream*/
final Stream<String> stream4 = /*some stream*/
final Stream<String> stream5 = /*some stream*/
final Stream<String> stream = Stream.of(stream1, stream2, stream3, stream4, stream5).flatMap(Function.identity());
}
In jouw voorbeeld:
Stream<Integer> resultStream = Stream.of(stream1, stream2, Stream.of(element))
.flatMap(identity())
.filter(x -> x != 0)
.filter(x -> x != 1)
.filter(x -> x != 2);
Antwoord 2, autoriteit 70%
Afgeleid van een bericht in de thread gelinkt door @RohitJain:
Stream.of(s1, s2, s3, ...)
/* .parallel() if you want*/
.reduce(Stream::concat)
.orElseGet(Stream::empty);
Antwoord 3, autoriteit 18%
In Google Guava v21.0+ is er:
com.google.common.collect.Streams#concat
methode
Antwoord 4, autoriteit 2%
SO, antwoorden verzamelen of.flatMap()vs of.reduce().orElseGet(): of.flatMap
kan geen oneindige streams verwerken, wanneer of.reduce()
– kan. Zie het testvoorbeeld hieronder:
@RunWith(JUnit4.class)
public class StreamConcatTest {
@Rule
public Timeout globalTimeout = Timeout.seconds(3);
private static final Random randomSupplier = new Random(System.currentTimeMillis());
private Stream<Stream<Integer>> mergedStream;
@Before
public void setUp() throws Exception {
Stream<Integer> infinite = Stream.concat(
Stream.of(1, 2, 3, 4, 5),
Stream.generate(randomSupplier::nextInt)
);
Stream<Integer> finite1 = Stream.of(100, 101, 102, 103);
Stream<Integer> finite2 = Stream.of(222, 333, 444, 555);
mergedStream = Stream.of(infinite, finite1, finite2);
}
@Test
public void of_flatMap_FAILS_BY_TIMEOUT() throws Exception {
Stream<Integer> streamToTest = mergedStream
.flatMap(i -> i);
assertThat(streamToTest
.skip(3)
.findFirst() // this should break infinite stream, but can't
.orElse(-1),
is(4));
}
@Test
public void of_reduce_SUCCESS() throws Exception {
Stream<Integer> streamToTest = mergedStream
.reduce(Stream::concat)
.orElseGet(Stream::empty);
assertThat(streamToTest
.skip(3)
.findFirst() // this really breaks infinite stream
.orElse(-1),
is(4));
}
}