-1

The below for loop produces a collection of lambda expressions.

 Callable<String>[] tasks = new Callable[messageCount];
 for (int i = 0; i < count; i++) {
   tasks[i] = () -> msg;
 }

Trying the same with stream forEach produces nulls.

 Arrays.stream(tasks).forEach(t -> {
   t = () -> message;
 });

What am i missing? How do I fix this?

Elango
  • 13
  • 1

2 Answers2

2

In your first code sample, you are assigning the lambda expression () -> msg to each element of the tasks array.

However, in the second example, you are assigning the lambda expression () -> msg to a temporary variable t with type Callable<String>. The intention of Stream#forEach is to pass the elements of the stream to a consumer that uses the elements in some way. If you assign to the consumer's parameter in some way, the source of the stream will not reflect that. Such an operation might not even make any sense:

IntStream.range(1,10).filter((x) -> (x % 2 == 0)).forEach((x) -> {++x;});

This ties to a general theme of Java streams: they are unidirectional pipelines for producing, transforming, filtering, and consuming data. As data flows from the Arrays.stream supplier, it can only flow in one direction, into the consumer (forEach); changes made downstream will not propagate back upstream.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • Thanks so much for explaining the stream concept that I didnt fully understood earlier. This makes perfect sense. – Elango Jul 04 '19 at 20:45
0

Your stream code is equivalent to the following for loop:

for (Callable<String> t : tasks) {
    t = () -> message;
}

which itself is equivalent to:

for (int i = 0; i < tasks.length; i++) {
    Callable<String> t = tasks[i];
    t = () -> msg;
}

Change the value of t does not change the value of tasks[i].

To create an array of length messageCount, with elements being lambda expressions, use streaming:

Callable<String>[] tasks = IntStream.range(0, messageCount)
                                    .mapToObj(i -> (Callable<String>) () -> msg)
                                    .toArray(Callable[]::new);
Andreas
  • 154,647
  • 11
  • 152
  • 247