1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.util.stream;
26
27import java.lang.reflect.Method;
28import java.lang.reflect.Modifier;
29import java.util.Comparator;
30import java.util.DoubleSummaryStatistics;
31import java.util.IntSummaryStatistics;
32import java.util.Iterator;
33import java.util.LongSummaryStatistics;
34import java.util.Optional;
35import java.util.OptionalDouble;
36import java.util.OptionalInt;
37import java.util.OptionalLong;
38import java.util.PrimitiveIterator;
39import java.util.Set;
40import java.util.Spliterator;
41import java.util.function.BiConsumer;
42import java.util.function.BiFunction;
43import java.util.function.BinaryOperator;
44import java.util.function.Consumer;
45import java.util.function.DoubleBinaryOperator;
46import java.util.function.DoubleConsumer;
47import java.util.function.DoubleFunction;
48import java.util.function.DoublePredicate;
49import java.util.function.DoubleToIntFunction;
50import java.util.function.DoubleToLongFunction;
51import java.util.function.DoubleUnaryOperator;
52import java.util.function.Function;
53import java.util.function.IntBinaryOperator;
54import java.util.function.IntConsumer;
55import java.util.function.IntFunction;
56import java.util.function.IntPredicate;
57import java.util.function.IntToDoubleFunction;
58import java.util.function.IntToLongFunction;
59import java.util.function.IntUnaryOperator;
60import java.util.function.LongBinaryOperator;
61import java.util.function.LongConsumer;
62import java.util.function.LongFunction;
63import java.util.function.LongPredicate;
64import java.util.function.LongToDoubleFunction;
65import java.util.function.LongToIntFunction;
66import java.util.function.LongUnaryOperator;
67import java.util.function.ObjDoubleConsumer;
68import java.util.function.ObjIntConsumer;
69import java.util.function.ObjLongConsumer;
70import java.util.function.Predicate;
71import java.util.function.Supplier;
72import java.util.function.ToDoubleFunction;
73
74import java.util.function.ToIntFunction;
75import java.util.function.ToLongFunction;
76
77import static java.util.stream.Collectors.*;
78
79public final class DefaultMethodStreams {
80
81    static {
82        // Verify that default methods are not overridden
83        verify(DefaultMethodRefStream.class);
84        verify(DefaultMethodIntStream.class);
85        verify(DefaultMethodLongStream.class);
86        verify(DefaultMethodDoubleStream.class);
87    }
88
89    static void verify(Class<?> del) {
90        // Find the stream interface
91        Class<?> s = Stream.of(del.getInterfaces())
92                .filter(c -> BaseStream.class.isAssignableFrom(c))
93                .findFirst().get();
94
95        // Get all default methods on the stream class
96        Set<String> dms = Stream.of(s.getMethods())
97                .filter(m -> !Modifier.isStatic(m.getModifiers()))
98                .filter(m -> !m.isBridge())
99                .filter(Method::isDefault)
100                .map(Method::getName)
101                .collect(toSet());
102
103        // Get all methods on the delegating class
104        Set<String> ims = Stream.of(del.getMethods())
105                .filter(m -> !Modifier.isStatic(m.getModifiers()))
106                .filter(m -> m.getDeclaringClass() == del)
107                .map(Method::getName)
108                .collect(toSet());
109
110        if (ims.stream().anyMatch(dms::contains)) {
111            throw new AssertionError(String.format("%s overrides default methods of %s\n", del, s));
112        }
113    }
114
115    /**
116     * Creates a stream that for the next operation either delegates to
117     * a default method on {@link Stream}, if present for that operation,
118     * otherwise delegates to an underlying stream.
119     *
120     * @param s the underlying stream to be delegated to for non-default
121     * methods.
122     * @param <T> the type of the stream elements
123     * @return the delegating stream
124     */
125    public static <T> Stream<T> delegateTo(Stream<T> s) {
126        return new DefaultMethodRefStream<>(s);
127    }
128
129    /**
130     * Creates a stream that for the next operation either delegates to
131     * a default method on {@link IntStream}, if present for that operation,
132     * otherwise delegates to an underlying stream.
133     *
134     * @param s the underlying stream to be delegated to for non-default
135     * methods.
136     * @return the delegating stream
137     */
138    public static IntStream delegateTo(IntStream s) {
139        return new DefaultMethodIntStream(s);
140    }
141
142    /**
143     * Creates a stream that for the next operation either delegates to
144     * a default method on {@link LongStream}, if present for that operation,
145     * otherwise delegates to an underlying stream.
146     *
147     * @param s the underlying stream to be delegated to for non-default
148     * methods.
149     * @return the delegating stream
150     */
151    public static LongStream delegateTo(LongStream s) {
152        return new DefaultMethodLongStream(s);
153    }
154
155    /**
156     * Creates a stream that for the next operation either delegates to
157     * a default method on {@link DoubleStream}, if present for that operation,
158     * otherwise delegates to an underlying stream.
159     *
160     * @param s the underlying stream to be delegated to for non-default
161     * methods.
162     * @return the delegating stream
163     */
164    public static DoubleStream delegateTo(DoubleStream s) {
165        return new DefaultMethodDoubleStream(s);
166    }
167
168    /**
169     * A stream that delegates the next operation to a default method, if
170     * present, or to the same operation of an underlying stream.
171     *
172     * @param <T> the type of the stream elements
173     */
174    static final class DefaultMethodRefStream<T> implements Stream<T> {
175        final Stream<T> s;
176
177        DefaultMethodRefStream(Stream<T> s) {
178            this.s = s;
179        }
180
181
182        // Delegating non-default methods
183
184        @Override
185        public Stream<T> filter(Predicate<? super T> predicate) {
186            return s.filter(predicate);
187        }
188
189        @Override
190        public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
191            return s.map(mapper);
192        }
193
194        @Override
195        public IntStream mapToInt(ToIntFunction<? super T> mapper) {
196            return s.mapToInt(mapper);
197        }
198
199        @Override
200        public LongStream mapToLong(ToLongFunction<? super T> mapper) {
201            return s.mapToLong(mapper);
202        }
203
204        @Override
205        public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
206            return s.mapToDouble(mapper);
207        }
208
209        @Override
210        public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
211            return s.flatMap(mapper);
212        }
213
214        @Override
215        public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
216            return s.flatMapToInt(mapper);
217        }
218
219        @Override
220        public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
221            return s.flatMapToLong(mapper);
222        }
223
224        @Override
225        public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
226            return s.flatMapToDouble(mapper);
227        }
228
229        @Override
230        public Stream<T> distinct() {
231            return s.distinct();
232        }
233
234        @Override
235        public Stream<T> sorted() {
236            return s.sorted();
237        }
238
239        @Override
240        public Stream<T> sorted(Comparator<? super T> comparator) {
241            return s.sorted(comparator);
242        }
243
244        @Override
245        public Stream<T> peek(Consumer<? super T> action) {
246            return s.peek(action);
247        }
248
249        @Override
250        public Stream<T> limit(long maxSize) {
251            return s.limit(maxSize);
252        }
253
254        @Override
255        public Stream<T> skip(long n) {
256            return s.skip(n);
257        }
258
259        @Override
260        public void forEach(Consumer<? super T> action) {
261            s.forEach(action);
262        }
263
264        @Override
265        public void forEachOrdered(Consumer<? super T> action) {
266            s.forEachOrdered(action);
267        }
268
269        @Override
270        public Object[] toArray() {
271            return s.toArray();
272        }
273
274        @Override
275        public <A> A[] toArray(IntFunction<A[]> generator) {
276            return s.toArray(generator);
277        }
278
279        @Override
280        public T reduce(T identity, BinaryOperator<T> accumulator) {
281            return s.reduce(identity, accumulator);
282        }
283
284        @Override
285        public Optional<T> reduce(BinaryOperator<T> accumulator) {
286            return s.reduce(accumulator);
287        }
288
289        @Override
290        public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
291            return s.reduce(identity, accumulator, combiner);
292        }
293
294        @Override
295        public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
296            return s.collect(supplier, accumulator, combiner);
297        }
298
299        @Override
300        public <R, A> R collect(Collector<? super T, A, R> collector) {
301            return s.collect(collector);
302        }
303
304        @Override
305        public Optional<T> min(Comparator<? super T> comparator) {
306            return s.min(comparator);
307        }
308
309        @Override
310        public Optional<T> max(Comparator<? super T> comparator) {
311            return s.max(comparator);
312        }
313
314        @Override
315        public long count() {
316            return s.count();
317        }
318
319        @Override
320        public boolean anyMatch(Predicate<? super T> predicate) {
321            return s.anyMatch(predicate);
322        }
323
324        @Override
325        public boolean allMatch(Predicate<? super T> predicate) {
326            return s.allMatch(predicate);
327        }
328
329        @Override
330        public boolean noneMatch(Predicate<? super T> predicate) {
331            return s.noneMatch(predicate);
332        }
333
334        @Override
335        public Optional<T> findFirst() {
336            return s.findFirst();
337        }
338
339        @Override
340        public Optional<T> findAny() {
341            return s.findAny();
342        }
343
344        @Override
345        public Iterator<T> iterator() {
346            return s.iterator();
347        }
348
349        @Override
350        public Spliterator<T> spliterator() {
351            return s.spliterator();
352        }
353
354        @Override
355        public boolean isParallel() {
356            return s.isParallel();
357        }
358
359        @Override
360        public Stream<T> sequential() {
361            return s.sequential();
362        }
363
364        @Override
365        public Stream<T> parallel() {
366            return s.parallel();
367        }
368
369        @Override
370        public Stream<T> unordered() {
371            return s.unordered();
372        }
373
374        @Override
375        public Stream<T> onClose(Runnable closeHandler) {
376            return s.onClose(closeHandler);
377        }
378
379        @Override
380        public void close() {
381            s.close();
382        }
383    }
384
385    static final class DefaultMethodIntStream implements IntStream {
386        final IntStream s;
387
388        public DefaultMethodIntStream(IntStream s) {
389            this.s = s;
390        }
391
392
393        // Delegating non-default methods
394
395        @Override
396        public IntStream filter(IntPredicate predicate) {
397            return s.filter(predicate);
398        }
399
400        @Override
401        public IntStream map(IntUnaryOperator mapper) {
402            return s.map(mapper);
403        }
404
405        @Override
406        public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
407            return s.mapToObj(mapper);
408        }
409
410        @Override
411        public LongStream mapToLong(IntToLongFunction mapper) {
412            return s.mapToLong(mapper);
413        }
414
415        @Override
416        public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
417            return s.mapToDouble(mapper);
418        }
419
420        @Override
421        public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
422            return s.flatMap(mapper);
423        }
424
425        @Override
426        public IntStream distinct() {
427            return s.distinct();
428        }
429
430        @Override
431        public IntStream sorted() {
432            return s.sorted();
433        }
434
435        @Override
436        public IntStream peek(IntConsumer action) {
437            return s.peek(action);
438        }
439
440        @Override
441        public IntStream limit(long maxSize) {
442            return s.limit(maxSize);
443        }
444
445        @Override
446        public IntStream skip(long n) {
447            return s.skip(n);
448        }
449
450        @Override
451        public void forEach(IntConsumer action) {
452            s.forEach(action);
453        }
454
455        @Override
456        public void forEachOrdered(IntConsumer action) {
457            s.forEachOrdered(action);
458        }
459
460        @Override
461        public int[] toArray() {
462            return s.toArray();
463        }
464
465        @Override
466        public int reduce(int identity, IntBinaryOperator op) {
467            return s.reduce(identity, op);
468        }
469
470        @Override
471        public OptionalInt reduce(IntBinaryOperator op) {
472            return s.reduce(op);
473        }
474
475        @Override
476        public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
477            return s.collect(supplier, accumulator, combiner);
478        }
479
480        @Override
481        public int sum() {
482            return s.sum();
483        }
484
485        @Override
486        public OptionalInt min() {
487            return s.min();
488        }
489
490        @Override
491        public OptionalInt max() {
492            return s.max();
493        }
494
495        @Override
496        public long count() {
497            return s.count();
498        }
499
500        @Override
501        public OptionalDouble average() {
502            return s.average();
503        }
504
505        @Override
506        public IntSummaryStatistics summaryStatistics() {
507            return s.summaryStatistics();
508        }
509
510        @Override
511        public boolean anyMatch(IntPredicate predicate) {
512            return s.anyMatch(predicate);
513        }
514
515        @Override
516        public boolean allMatch(IntPredicate predicate) {
517            return s.allMatch(predicate);
518        }
519
520        @Override
521        public boolean noneMatch(IntPredicate predicate) {
522            return s.noneMatch(predicate);
523        }
524
525        @Override
526        public OptionalInt findFirst() {
527            return s.findFirst();
528        }
529
530        @Override
531        public OptionalInt findAny() {
532            return s.findAny();
533        }
534
535        @Override
536        public LongStream asLongStream() {
537            return s.asLongStream();
538        }
539
540        @Override
541        public DoubleStream asDoubleStream() {
542            return s.asDoubleStream();
543        }
544
545        @Override
546        public Stream<Integer> boxed() {
547            return s.boxed();
548        }
549
550        @Override
551        public IntStream sequential() {
552            return s.sequential();
553        }
554
555        @Override
556        public IntStream parallel() {
557            return s.parallel();
558        }
559
560        @Override
561        public PrimitiveIterator.OfInt iterator() {
562            return s.iterator();
563        }
564
565        @Override
566        public Spliterator.OfInt spliterator() {
567            return s.spliterator();
568        }
569
570        @Override
571        public boolean isParallel() {
572            return s.isParallel();
573        }
574
575        @Override
576        public IntStream unordered() {
577            return s.unordered();
578        }
579
580        @Override
581        public IntStream onClose(Runnable closeHandler) {
582            return s.onClose(closeHandler);
583        }
584
585        @Override
586        public void close() {
587            s.close();
588        }
589    }
590
591    static final class DefaultMethodLongStream implements LongStream {
592        final LongStream s;
593
594        public DefaultMethodLongStream(LongStream s) {
595            this.s = s;
596        }
597
598
599        // Delegating non-default methods
600
601        @Override
602        public void forEach(LongConsumer action) {
603            s.forEach(action);
604        }
605
606        @Override
607        public LongStream filter(LongPredicate predicate) {
608            return s.filter(predicate);
609        }
610
611        @Override
612        public LongStream map(LongUnaryOperator mapper) {
613            return s.map(mapper);
614        }
615
616        @Override
617        public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
618            return s.mapToObj(mapper);
619        }
620
621        @Override
622        public IntStream mapToInt(LongToIntFunction mapper) {
623            return s.mapToInt(mapper);
624        }
625
626        @Override
627        public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
628            return s.mapToDouble(mapper);
629        }
630
631        @Override
632        public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
633            return s.flatMap(mapper);
634        }
635
636        @Override
637        public LongStream distinct() {
638            return s.distinct();
639        }
640
641        @Override
642        public LongStream sorted() {
643            return s.sorted();
644        }
645
646        @Override
647        public LongStream peek(LongConsumer action) {
648            return s.peek(action);
649        }
650
651        @Override
652        public LongStream limit(long maxSize) {
653            return s.limit(maxSize);
654        }
655
656        @Override
657        public LongStream skip(long n) {
658            return s.skip(n);
659        }
660
661        @Override
662        public void forEachOrdered(LongConsumer action) {
663            s.forEachOrdered(action);
664        }
665
666        @Override
667        public long[] toArray() {
668            return s.toArray();
669        }
670
671        @Override
672        public long reduce(long identity, LongBinaryOperator op) {
673            return s.reduce(identity, op);
674        }
675
676        @Override
677        public OptionalLong reduce(LongBinaryOperator op) {
678            return s.reduce(op);
679        }
680
681        @Override
682        public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
683            return s.collect(supplier, accumulator, combiner);
684        }
685
686        @Override
687        public long sum() {
688            return s.sum();
689        }
690
691        @Override
692        public OptionalLong min() {
693            return s.min();
694        }
695
696        @Override
697        public OptionalLong max() {
698            return s.max();
699        }
700
701        @Override
702        public long count() {
703            return s.count();
704        }
705
706        @Override
707        public OptionalDouble average() {
708            return s.average();
709        }
710
711        @Override
712        public LongSummaryStatistics summaryStatistics() {
713            return s.summaryStatistics();
714        }
715
716        @Override
717        public boolean anyMatch(LongPredicate predicate) {
718            return s.anyMatch(predicate);
719        }
720
721        @Override
722        public boolean allMatch(LongPredicate predicate) {
723            return s.allMatch(predicate);
724        }
725
726        @Override
727        public boolean noneMatch(LongPredicate predicate) {
728            return s.noneMatch(predicate);
729        }
730
731        @Override
732        public OptionalLong findFirst() {
733            return s.findFirst();
734        }
735
736        @Override
737        public OptionalLong findAny() {
738            return s.findAny();
739        }
740
741        @Override
742        public DoubleStream asDoubleStream() {
743            return s.asDoubleStream();
744        }
745
746        @Override
747        public Stream<Long> boxed() {
748            return s.boxed();
749        }
750
751        @Override
752        public LongStream sequential() {
753            return s.sequential();
754        }
755
756        @Override
757        public LongStream parallel() {
758            return s.parallel();
759        }
760
761        @Override
762        public PrimitiveIterator.OfLong iterator() {
763            return s.iterator();
764        }
765
766        @Override
767        public Spliterator.OfLong spliterator() {
768            return s.spliterator();
769        }
770
771        @Override
772        public boolean isParallel() {
773            return s.isParallel();
774        }
775
776        @Override
777        public LongStream unordered() {
778            return s.unordered();
779        }
780
781        @Override
782        public LongStream onClose(Runnable closeHandler) {
783            return s.onClose(closeHandler);
784        }
785
786        @Override
787        public void close() {
788            s.close();
789        }
790    }
791
792    static final class DefaultMethodDoubleStream implements DoubleStream {
793        final DoubleStream s;
794
795        public DefaultMethodDoubleStream(DoubleStream s) {
796            this.s = s;
797        }
798
799        @Override
800        public DoubleStream filter(DoublePredicate predicate) {
801            return s.filter(predicate);
802        }
803
804        @Override
805        public DoubleStream map(DoubleUnaryOperator mapper) {
806            return s.map(mapper);
807        }
808
809        @Override
810        public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
811            return s.mapToObj(mapper);
812        }
813
814        @Override
815        public IntStream mapToInt(DoubleToIntFunction mapper) {
816            return s.mapToInt(mapper);
817        }
818
819        @Override
820        public LongStream mapToLong(DoubleToLongFunction mapper) {
821            return s.mapToLong(mapper);
822        }
823
824        @Override
825        public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
826            return s.flatMap(mapper);
827        }
828
829        @Override
830        public DoubleStream distinct() {
831            return s.distinct();
832        }
833
834        @Override
835        public DoubleStream sorted() {
836            return s.sorted();
837        }
838
839        @Override
840        public DoubleStream peek(DoubleConsumer action) {
841            return s.peek(action);
842        }
843
844        @Override
845        public DoubleStream limit(long maxSize) {
846            return s.limit(maxSize);
847        }
848
849        @Override
850        public DoubleStream skip(long n) {
851            return s.skip(n);
852        }
853
854        @Override
855        public void forEach(DoubleConsumer action) {
856            s.forEach(action);
857        }
858
859        @Override
860        public void forEachOrdered(DoubleConsumer action) {
861            s.forEachOrdered(action);
862        }
863
864        @Override
865        public double[] toArray() {
866            return s.toArray();
867        }
868
869        @Override
870        public double reduce(double identity, DoubleBinaryOperator op) {
871            return s.reduce(identity, op);
872        }
873
874        @Override
875        public OptionalDouble reduce(DoubleBinaryOperator op) {
876            return s.reduce(op);
877        }
878
879        @Override
880        public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
881            return s.collect(supplier, accumulator, combiner);
882        }
883
884        @Override
885        public double sum() {
886            return s.sum();
887        }
888
889        @Override
890        public OptionalDouble min() {
891            return s.min();
892        }
893
894        @Override
895        public OptionalDouble max() {
896            return s.max();
897        }
898
899        @Override
900        public long count() {
901            return s.count();
902        }
903
904        @Override
905        public OptionalDouble average() {
906            return s.average();
907        }
908
909        @Override
910        public DoubleSummaryStatistics summaryStatistics() {
911            return s.summaryStatistics();
912        }
913
914        @Override
915        public boolean anyMatch(DoublePredicate predicate) {
916            return s.anyMatch(predicate);
917        }
918
919        @Override
920        public boolean allMatch(DoublePredicate predicate) {
921            return s.allMatch(predicate);
922        }
923
924        @Override
925        public boolean noneMatch(DoublePredicate predicate) {
926            return s.noneMatch(predicate);
927        }
928
929        @Override
930        public OptionalDouble findFirst() {
931            return s.findFirst();
932        }
933
934        @Override
935        public OptionalDouble findAny() {
936            return s.findAny();
937        }
938
939        @Override
940        public Stream<Double> boxed() {
941            return s.boxed();
942        }
943
944        @Override
945        public DoubleStream sequential() {
946            return s.sequential();
947        }
948
949        @Override
950        public DoubleStream parallel() {
951            return s.parallel();
952        }
953
954        @Override
955        public PrimitiveIterator.OfDouble iterator() {
956            return s.iterator();
957        }
958
959        @Override
960        public Spliterator.OfDouble spliterator() {
961            return s.spliterator();
962        }
963
964        @Override
965        public boolean isParallel() {
966            return s.isParallel();
967        }
968
969        @Override
970        public DoubleStream unordered() {
971            return s.unordered();
972        }
973
974        @Override
975        public DoubleStream onClose(Runnable closeHandler) {
976            return s.onClose(closeHandler);
977        }
978
979        @Override
980        public void close() {
981            s.close();
982        }
983    }
984}
985