748 } |
748 } |
749 |
749 |
750 /** |
750 /** |
751 * Returns a sequential {@code LongStream} from {@code startInclusive} |
751 * Returns a sequential {@code LongStream} from {@code startInclusive} |
752 * (inclusive) to {@code endExclusive} (exclusive) by an incremental step of |
752 * (inclusive) to {@code endExclusive} (exclusive) by an incremental step of |
753 * 1. |
753 * {@code 1}. |
754 * |
754 * |
755 * @implSpec |
755 * @apiNote |
756 * The implementation behaves as if: |
756 * <p>An equivalent sequence of increasing values can be produced |
757 * <pre>{@code |
757 * sequentially using a {@code for} loop as follows: |
758 * longRange(startInclusive, endExclusive, 1); |
758 * <pre>{@code |
|
759 * for (long i = startInclusive; i < endExclusive ; i++) { ... } |
759 * }</pre> |
760 * }</pre> |
760 * |
761 * |
761 * @param startInclusive the (inclusive) initial value |
762 * @param startInclusive the (inclusive) initial value |
762 * @param endExclusive the exclusive upper bound |
763 * @param endExclusive the exclusive upper bound |
763 * @return a sequential {@code LongStream} for the range of {@code long} |
764 * @return a sequential {@code LongStream} for the range of {@code long} |
764 * elements |
765 * elements |
765 */ |
766 */ |
766 public static LongStream range(long startInclusive, final long endExclusive) { |
767 public static LongStream range(long startInclusive, final long endExclusive) { |
767 return range(startInclusive, endExclusive, 1); |
768 if (startInclusive >= endExclusive) { |
|
769 return empty(); |
|
770 } else if (endExclusive - startInclusive < 0) { |
|
771 // Size of range > Long.MAX_VALUE |
|
772 // Split the range in two and concatenate |
|
773 // Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE) then |
|
774 // the lower range, [Long.MIN_VALUE, 0) will be further split in two |
|
775 // long m = startInclusive + Long.divideUnsigned(endExclusive - startInclusive, 2) + 1; |
|
776 // return Streams.concat(range(startInclusive, m), range(m, endExclusive)); |
|
777 // This is temporary until Streams.concat is supported |
|
778 throw new UnsupportedOperationException(); |
|
779 } else { |
|
780 return StreamSupport.longStream( |
|
781 new Streams.RangeLongSpliterator(startInclusive, endExclusive, false)); |
|
782 } |
768 } |
783 } |
769 |
784 |
770 /** |
785 /** |
771 * Returns a sequential {@code LongStream} from {@code startInclusive} |
786 * Returns a sequential {@code LongStream} from {@code startInclusive} |
772 * (inclusive) to {@code endExclusive} (exclusive) by {@code step}. If |
787 * (inclusive) to {@code endInclusive} (inclusive) by an incremental step of |
773 * {@code startInclusive} is greater than or equal to {@code |
788 * {@code 1}. |
774 * endExclusive}, an empty stream is returned. |
789 * |
775 * |
790 * @apiNote |
776 * <p>An equivalent sequence of increasing values can be produced |
791 * <p>An equivalent sequence of increasing values can be produced |
777 * sequentially using a {@code for} loop as follows: |
792 * sequentially using a {@code for} loop as follows: |
778 * <pre>{@code |
793 * <pre>{@code |
779 * for (long i = startInclusive; i < endExclusive ; i += step) { ... } |
794 * for (long i = startInclusive; i <= endInclusive ; i++) { ... } |
780 * }</pre> |
795 * }</pre> |
781 * |
796 * |
782 * @param startInclusive the (inclusive) initial value |
797 * @param startInclusive the (inclusive) initial value |
783 * @param endExclusive the exclusive upper bound |
798 * @param endInclusive the inclusive upper bound |
784 * @param step the difference between consecutive values |
|
785 * @return a sequential {@code LongStream} for the range of {@code long} |
799 * @return a sequential {@code LongStream} for the range of {@code long} |
786 * elements |
800 * elements |
787 * @throws IllegalArgumentException if {@code step} is less than or equal to |
801 */ |
788 * 0 |
802 public static LongStream rangeClosed(long startInclusive, final long endInclusive) { |
789 */ |
803 if (startInclusive > endInclusive) { |
790 public static LongStream range(long startInclusive, final long endExclusive, final long step) { |
|
791 if (step <= 0) { |
|
792 throw new IllegalArgumentException(String.format("Illegal step: %d", step)); |
|
793 } else if (startInclusive >= endExclusive) { |
|
794 return empty(); |
804 return empty(); |
|
805 } else if (endInclusive - startInclusive + 1 <= 0) { |
|
806 // Size of range > Long.MAX_VALUE |
|
807 // Split the range in two and concatenate |
|
808 // Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE] then |
|
809 // the lower range, [Long.MIN_VALUE, 0), and upper range, |
|
810 // [0, Long.MAX_VALUE], will both be further split in two |
|
811 // long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1; |
|
812 // return Streams.concat(range(startInclusive, m), rangeClosed(m, endInclusive)); |
|
813 // This is temporary until Streams.concat is supported |
|
814 throw new UnsupportedOperationException(); |
795 } else { |
815 } else { |
796 return StreamSupport.longStream(new Streams.RangeLongSpliterator(startInclusive, endExclusive, step)); |
816 return StreamSupport.longStream( |
|
817 new Streams.RangeLongSpliterator(startInclusive, endInclusive, true)); |
797 } |
818 } |
798 } |
819 } |
799 } |
820 } |