Changing signature of traverse and sequence to return java.lang.Iterable, updated docs as well, closing #847
This commit is contained in:
parent
3ab4cab660
commit
5b54de7f48
3 changed files with 22 additions and 21 deletions
|
|
@ -4,6 +4,7 @@ import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.lang.Iterable;
|
||||||
import akka.japi.Function;
|
import akka.japi.Function;
|
||||||
import akka.japi.Function2;
|
import akka.japi.Function2;
|
||||||
import akka.japi.Procedure;
|
import akka.japi.Procedure;
|
||||||
|
|
@ -43,7 +44,7 @@ public class JavaFutureTests {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<LinkedList<String>> futureList = sequence(listFutures);
|
Future<Iterable<String>> futureList = sequence(listFutures);
|
||||||
|
|
||||||
assertEquals(futureList.get(), listExpected);
|
assertEquals(futureList.get(), listExpected);
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +103,7 @@ public class JavaFutureTests {
|
||||||
listStrings.add("test");
|
listStrings.add("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<LinkedList<String>> result = traverse(listStrings, new Function<String,Future<String>>(){
|
Future<Iterable<String>> result = traverse(listStrings, new Function<String,Future<String>>(){
|
||||||
public Future<String> apply(final String r) {
|
public Future<String> apply(final String r) {
|
||||||
return future(new Callable<String>() {
|
return future(new Callable<String>() {
|
||||||
public String call() {
|
public String call() {
|
||||||
|
|
|
||||||
|
|
@ -159,10 +159,10 @@ object Futures {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java API.
|
* Java API.
|
||||||
* Simple version of Futures.traverse. Transforms a java.lang.Iterable[Future[A]] into a Future[java.util.LinkedList[A]].
|
* Simple version of Futures.traverse. Transforms a java.lang.Iterable[Future[A]] into a Future[java.lang.Iterable[A]].
|
||||||
* Useful for reducing many Futures into a single Future.
|
* Useful for reducing many Futures into a single Future.
|
||||||
*/
|
*/
|
||||||
def sequence[A](in: JIterable[Future[A]], timeout: Long): Future[JLinkedList[A]] =
|
def sequence[A](in: JIterable[Future[A]], timeout: Long): Future[JIterable[A]] =
|
||||||
scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(Future(new JLinkedList[A]()))((fr, fa) =>
|
scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(Future(new JLinkedList[A]()))((fr, fa) =>
|
||||||
for (r <- fr; a <- fa) yield {
|
for (r <- fr; a <- fa) yield {
|
||||||
r add a
|
r add a
|
||||||
|
|
@ -171,18 +171,18 @@ object Futures {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java API.
|
* Java API.
|
||||||
* Simple version of Futures.traverse. Transforms a java.lang.Iterable[Future[A]] into a Future[java.util.LinkedList[A]].
|
* Simple version of Futures.traverse. Transforms a java.lang.Iterable[Future[A]] into a Future[java.lang.Iterable[A]].
|
||||||
* Useful for reducing many Futures into a single Future.
|
* Useful for reducing many Futures into a single Future.
|
||||||
*/
|
*/
|
||||||
def sequence[A](in: JIterable[Future[A]]): Future[JLinkedList[A]] = sequence(in, Actor.TIMEOUT)
|
def sequence[A](in: JIterable[Future[A]]): Future[JIterable[A]] = sequence(in, Actor.TIMEOUT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java API.
|
* Java API.
|
||||||
* Transforms a java.lang.Iterable[A] into a Future[java.util.LinkedList[B]] using the provided Function A => Future[B].
|
* Transforms a java.lang.Iterable[A] into a Future[java.lang.Iterable[B]] using the provided Function A => Future[B].
|
||||||
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
|
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*/
|
*/
|
||||||
def traverse[A, B](in: JIterable[A], timeout: Long, fn: JFunc[A,Future[B]]): Future[JLinkedList[B]] =
|
def traverse[A, B](in: JIterable[A], timeout: Long, fn: JFunc[A,Future[B]]): Future[JIterable[B]] =
|
||||||
scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(Future(new JLinkedList[B]())){(fr, a) =>
|
scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(Future(new JLinkedList[B]())){(fr, a) =>
|
||||||
val fb = fn(a)
|
val fb = fn(a)
|
||||||
for (r <- fr; b <- fb) yield {
|
for (r <- fr; b <- fb) yield {
|
||||||
|
|
@ -193,11 +193,11 @@ object Futures {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java API.
|
* Java API.
|
||||||
* Transforms a java.lang.Iterable[A] into a Future[java.util.LinkedList[B]] using the provided Function A => Future[B].
|
* Transforms a java.lang.Iterable[A] into a Future[java.lang.Iterable[B]] using the provided Function A => Future[B].
|
||||||
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
|
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
|
||||||
* in parallel.
|
* in parallel.
|
||||||
*/
|
*/
|
||||||
def traverse[A, B](in: JIterable[A], fn: JFunc[A,Future[B]]): Future[JLinkedList[B]] = traverse(in, Actor.TIMEOUT, fn)
|
def traverse[A, B](in: JIterable[A], fn: JFunc[A,Future[B]]): Future[JIterable[B]] = traverse(in, Actor.TIMEOUT, fn)
|
||||||
|
|
||||||
// =====================================
|
// =====================================
|
||||||
// Deprecations
|
// Deprecations
|
||||||
|
|
|
||||||
|
|
@ -172,12 +172,12 @@ It is very often desirable to be able to combine different Futures with eachothe
|
||||||
import akka.dispatch.Future;
|
import akka.dispatch.Future;
|
||||||
import static akka.dispatch.Futures.sequence;
|
import static akka.dispatch.Futures.sequence;
|
||||||
import akka.japi.Function;
|
import akka.japi.Function;
|
||||||
import java.util.LinkedList;
|
import java.lang.Iterable;
|
||||||
|
|
||||||
LinkedList<Future<Integer>> listOfFutureInts = ... //Some source generating a list of Future<Integer>:s
|
Iterable<Future<Integer>> listOfFutureInts = ... //Some source generating a sequence of Future<Integer>:s
|
||||||
|
|
||||||
// now we have a Future[List[Int]]
|
// now we have a Future[Iterable[Int]]
|
||||||
Future<LinkedList<Integer>> futureListOfInts = sequence(listOfFutureInts);
|
Future<Iterable<Integer>> futureListOfInts = sequence(listOfFutureInts);
|
||||||
|
|
||||||
// Find the sum of the odd numbers
|
// Find the sum of the odd numbers
|
||||||
Long totalSum = futureListOfInts.map(
|
Long totalSum = futureListOfInts.map(
|
||||||
|
|
@ -190,21 +190,21 @@ It is very often desirable to be able to combine different Futures with eachothe
|
||||||
}
|
}
|
||||||
}).get();
|
}).get();
|
||||||
|
|
||||||
To better explain what happened in the example, ``Future.sequence`` is taking the ``LinkedList<Future<Integer>>`` and turning it into a ``Future<LinkedList<Integer>>``. We can then use ``map`` to work with the ``LinkedList<Integer>`` directly, and we aggregate the sum of the ``LinkedList``.
|
To better explain what happened in the example, ``Future.sequence`` is taking the ``Iterable<Future<Integer>>`` and turning it into a ``Future<Iterable<Integer>>``. We can then use ``map`` to work with the ``Iterable<Integer>`` directly, and we aggregate the sum of the ``Iterable``.
|
||||||
|
|
||||||
The ``traverse`` method is similar to ``sequence``, but it takes a sequence of ``A``s and applies a function from ``A`` to ``Future<B>`` and returns a ``Future<LinkedList<B>>``, enabling parallel ``map`` over the sequence, if you use ``Futures.future`` to create the ``Future``.
|
The ``traverse`` method is similar to ``sequence``, but it takes a sequence of ``A``s and applies a function from ``A`` to ``Future<B>`` and returns a ``Future<Iterable<B>>``, enabling parallel ``map`` over the sequence, if you use ``Futures.future`` to create the ``Future``.
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
import akka.dispatch.Future;
|
import akka.dispatch.Future;
|
||||||
import static akka.dispatch.Futures.traverse;
|
import static akka.dispatch.Futures.traverse;
|
||||||
import static akka.dispatch.Futures.future;
|
import static akka.dispatch.Futures.future;
|
||||||
import java.util.LinkedList;
|
import java.lang.Iterable;
|
||||||
import akka.japi.Function;
|
import akka.japi.Function;
|
||||||
|
|
||||||
LinkedList<String> listStrings = ... //Just a list of Strings
|
Iterable<String> listStrings = ... //Just a sequence of Strings
|
||||||
|
|
||||||
Future<LinkedList<String>> result = traverse(listStrings, new Function<String,Future<String>>(){
|
Future<Iterable<String>> result = traverse(listStrings, new Function<String,Future<String>>(){
|
||||||
public Future<String> apply(final String r) {
|
public Future<String> apply(final String r) {
|
||||||
return future(new Callable<String>() {
|
return future(new Callable<String>() {
|
||||||
public String call() {
|
public String call() {
|
||||||
|
|
@ -214,7 +214,7 @@ The ``traverse`` method is similar to ``sequence``, but it takes a sequence of `
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
result.get(); //Returns a the list of strings as upper case
|
result.get(); //Returns the sequence of strings as upper case
|
||||||
|
|
||||||
It's as simple as that!
|
It's as simple as that!
|
||||||
|
|
||||||
|
|
@ -224,7 +224,7 @@ Then there's a method that's called ``fold`` that takes a start-value, a sequenc
|
||||||
|
|
||||||
import akka.dispatch.Future;
|
import akka.dispatch.Future;
|
||||||
import static akka.dispatch.Futures.fold;
|
import static akka.dispatch.Futures.fold;
|
||||||
import java.util.Iterable;
|
import java.lang.Iterable;
|
||||||
import akka.japi.Function2;
|
import akka.japi.Function2;
|
||||||
|
|
||||||
Iterable<Future<String>> futures = ... //A sequence of Futures, in this case Strings
|
Iterable<Future<String>> futures = ... //A sequence of Futures, in this case Strings
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue