Jika Anda menambahkan impor statis untuk Stream.concat dan Stream.of , contoh pertama dapat ditulis sebagai berikut:
Stream<Foo> stream = concat(stream1, concat(stream2, of(element)));
Mengimpor metode statis dengan nama generik dapat menghasilkan kode yang menjadi sulit dibaca dan dipelihara ( polusi namespace ). Jadi, mungkin lebih baik untuk membuat metode statis Anda sendiri dengan nama yang lebih bermakna. Namun, untuk demonstrasi saya akan tetap menggunakan nama ini.
public static <T> Stream<T> concat(Stream<? extends T> lhs, Stream<? extends T> rhs) {
return Stream.concat(lhs, rhs);
}
public static <T> Stream<T> concat(Stream<? extends T> lhs, T rhs) {
return Stream.concat(lhs, Stream.of(rhs));
}
Dengan dua metode statis ini (opsional dikombinasikan dengan impor statis), dua contoh dapat ditulis sebagai berikut:
Stream<Foo> stream = concat(stream1, concat(stream2, element));
Stream<Foo> stream = concat(
concat(stream1.filter(x -> x!=0), stream2).filter(x -> x!=1),
element)
.filter(x -> x!=2);
Kode sekarang jauh lebih pendek. Namun, saya setuju bahwa keterbacaannya belum membaik. Jadi saya punya solusi lain.
Dalam banyak situasi, Kolektor dapat digunakan untuk memperluas fungsionalitas stream. Dengan dua Kolektor di bagian bawah, dua contoh dapat ditulis sebagai berikut:
Stream<Foo> stream = stream1.collect(concat(stream2)).collect(concat(element));
Stream<Foo> stream = stream1
.filter(x -> x!=0)
.collect(concat(stream2))
.filter(x -> x!=1)
.collect(concat(element))
.filter(x -> x!=2);
Satu-satunya perbedaan antara sintaks yang Anda inginkan dan sintaks di atas adalah, bahwa Anda harus mengganti concat (...) dengan collect (concat (...)) . Dua metode statis dapat diimplementasikan sebagai berikut (opsional digunakan dalam kombinasi dengan impor statis):
private static <T,A,R,S> Collector<T,?,S> combine(Collector<T,A,R> collector, Function<? super R, ? extends S> function) {
return Collector.of(
collector.supplier(),
collector.accumulator(),
collector.combiner(),
collector.finisher().andThen(function));
}
public static <T> Collector<T,?,Stream<T>> concat(Stream<? extends T> other) {
return combine(Collectors.toList(),
list -> Stream.concat(list.stream(), other));
}
public static <T> Collector<T,?,Stream<T>> concat(T element) {
return concat(Stream.of(element));
}
Tentu saja ada kekurangan dengan solusi ini yang harus disebutkan. collect adalah operasi terakhir yang menghabiskan semua elemen aliran. Selain itu, concat kolektor membuat ArrayList perantara setiap kali digunakan dalam rantai. Kedua operasi dapat memiliki dampak signifikan pada perilaku program Anda. Namun, jika keterbacaan lebih penting daripada kinerja , itu mungkin masih menjadi pendekatan yang sangat membantu.