public static <T>Stream<T> concat(Stream<? extends T> a,Stream<? extends T> b){
  Objects.requireNonNull(a);
  Objects.requireNonNull(b);
  @SuppressWarnings("unchecked") Spliterator<T> split=new Streams.ConcatSpliterator.OfRef<>((Spliterator<T>)a.spliterator(),(Spliterator<T>)b.spliterator());
  Stream<T> stream=StreamSupport.stream(split,a.isParallel() || b.isParallel());
  return stream.onClose(Streams.composedClose(a,b));
}

public static < T > Stream < T > concat ( Stream < ? extends T > a , Stream < ? extends T > b ) { Objects . requireNonNull ( a ) ; Objects . requireNonNull ( b ) ; @ SuppressWarnings ( "unchecked" ) Spliterator < T > split = new Streams . ConcatSpliterator . OfRef < > ( ( Spliterator < T > ) a . spliterator ( ) , ( Spliterator < T > ) b . spliterator ( ) ) ; Stream < T > stream = StreamSupport . stream ( split , a . isParallel ( ) || b . isParallel ( ) ) ; return stream . onClose ( Streams . composedClose ( a , b ) ) ; }
creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream . the resulting stream is ordered if both of the input streams are ordered , and parallel if either of the input streams is parallel . when the resulting stream is closed , the close handlers for both input streams are invoked .
