diff --git a/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java b/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java index 473b725c07..a4c13bda3d 100644 --- a/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java +++ b/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java @@ -467,12 +467,24 @@ public class SourceTest extends StreamTest { public void mustWorkFromRange() throws Exception { Future> f = Source.range(0, 10).grouped(20).runWith(Sink.> head(), materializer); final List result = Await.result(f, FiniteDuration.create(3, TimeUnit.SECONDS)); - assertEquals(result.size(), 11); + assertEquals(11, result.size()); Integer counter = 0; for (Integer i: result) assertEquals(i, counter++); } + @Test + public void mustWorkFromRangeWithStep() throws Exception { + Future> f = Source.range(0, 10, 2).grouped(20).runWith(Sink.> head(), materializer); + final List result = Await.result(f, FiniteDuration.create(3, TimeUnit.SECONDS)); + assertEquals(6, result.size()); + Integer counter = 0; + for (Integer i: result) { + assertEquals(i, counter); + counter+=2; + } + } + @Test public void mustRepeat() throws Exception { final Future> f = Source.repeat(42).grouped(10000).runWith(Sink.> head(), materializer); diff --git a/akka-stream/src/main/scala/akka/stream/javadsl/Source.scala b/akka-stream/src/main/scala/akka/stream/javadsl/Source.scala index 6b37e364bd..c96c1b478f 100644 --- a/akka-stream/src/main/scala/akka/stream/javadsl/Source.scala +++ b/akka-stream/src/main/scala/akka/stream/javadsl/Source.scala @@ -112,17 +112,28 @@ object Source { } /** - * Creates [[Source]] with `start` as the first element and each next element as `previous + 1` until - * it reaches `end`. It allows to create `Source` out of range as simply as on scala `Source(1 to N)` + * Creates [[Source]] that represents integer values in range ''[start;end]'', step equals to 1. + * It allows to create `Source` out of range as simply as on Scala `Source(1 to N)` + * + * Uses [[scala.collection.immutable.Range.inclusive(Int, Int)]] internally + * + * @see [[scala.collection.immutable.Range.inclusive(Int, Int)]] */ - def range(start: Int, end: Int): javadsl.Source[Integer, Unit] = { - require(start <= end, "start must be less or equal than end") - from(new util.AbstractList[Integer]() { - override def get(index: Int) = start + index - override def size = end - start + 1 - override def toString = s"Range($start to $end)" + def range(start: Int, end: Int): javadsl.Source[Integer, Unit] = range(start, end, 1) + + /** + * Creates [[Source]] that represents integer values in range ''[start;end]'', with the given step. + * It allows to create `Source` out of range as simply as on Scala `Source(1 to N)` + * + * Uses [[scala.collection.immutable.Range.inclusive(Int, Int, Int)]] internally + * + * @see [[scala.collection.immutable.Range.inclusive(Int, Int, Int)]] + */ + def range(start: Int, end: Int, step: Int): javadsl.Source[Integer, Unit] = + fromIterator[Integer](new function.Creator[util.Iterator[Integer]]() { + def create(): util.Iterator[Integer] = + Range.inclusive(start, end, step).iterator.asJava.asInstanceOf[util.Iterator[Integer]] }) - } /** * Start a new `Source` from the given `Future`. The stream will consist of