-2

say I desire to collect a list of doubles[] from a lambda function, I have created the following example, however it do not compile given the type. What could I do as a workaround?

public class CollectingStreams {
    public static double [] methodReturnArray(int n){
        return new double[] {1*n,2*n};
    }
    public static void main(String[] args){

        List<double[]> listArray= IntStream.range(0,5).parallel().forEach(
                (n) -> {methodReturnArray(n).collect(Collectors.toList());
                });
    }
}

Here is the compilation error:

java: cannot find symbol
  symbol:   method collect(java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.List<java.lang.Object>>)
  location: class double[]

As an attempt I have tried the following

        List<double[]> listArray= IntStream.range(0,5).parallel().forEach(
                (n) -> {
                    Arrays.stream(methodReturnArray(n)).collect(Collectors.toList());
                });

However it prompts this compilation error:

java: method collect in interface java.util.stream.DoubleStream cannot be applied to given types;
  required: java.util.function.Supplier<R>,java.util.function.ObjDoubleConsumer<R>,java.util.function.BiConsumer<R,R>
  found:    java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.List<java.lang.Object>>
  reason: cannot infer type-variable(s) R
    (actual and formal argument lists differ in length)

Moreover I have seen (here)[https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html] that fiven side effects it is best to avoid arrays favoring collecting to lists, therefore I must use Arrays with care.

I am not sure exactly how to properly cast or modify my attempts do that I can collect my list of double[].

Any thoughts?

Thanks

DTK
  • 95
  • 1
  • 9
  • 1
    The problem doesn't have anything to do with `double[]` and has everything to do with how you shouldn't be using `forEach` in this situation. – Louis Wasserman Feb 27 '22 at 18:03
  • Thanks @LouisWasserman, I am quite new to streams, would you suggest me to use another lambda approach? Or not using streams at all in this case? – DTK Feb 27 '22 at 18:08
  • 2
    `forEach` and `collect` are both terminal operations. Unlike intermidiate operations, terminal operations do not return a `Stream` but instead traverse the stream and produce a result. So they can not be combined. What you are looking for is called `map`. – magicmn Feb 27 '22 at 18:11

3 Answers3

1

Instead of the .forEach() use .mapToObject(), as forEach doesn't return anything that could be processed further.

This is the code I would try:

List<double[]> listArray = IntStream.range(0,5)
    .mapToObj(CollectingStreams::methodReturnArray)
    .collect(Collectors.toList());
cyberbrain
  • 3,433
  • 1
  • 12
  • 22
1

You don't need a method to return the array. You can do it like this.

 List<double[]> listArray= IntStream.range(0,5)
       .mapToObj(i->new double[]{i*1, i*2})
       .toList();                

listArray.forEach(s->System.out.println(Arrays.toString(s)));

prints

[0.0, 0.0]
[1.0, 2.0]
[2.0, 4.0]
[3.0, 6.0]
[4.0, 8.0]
WJS
  • 36,363
  • 4
  • 24
  • 39
0
List<int> numbers = new ArrayList<>();
List<double> numbers.stream().map(number -> (double) number).toList();
HotFlow
  • 11
  • 4