1
ArrayList<ArrayList<Float>> lists = new ArrayList<ArrayList<Float>>();

This is the arraylist I'm using. And I tried this:

float[][] trainingData = lists.stream()
                        .map(l -> l.stream()
                       .mapToFloat(Float::parseFloat)
                       .toArray())
                       .toArray(float[][]::new);

I'm getting this error :

The method mapToFloat(Float::parseFloat) is undefined for the type Stream

I must convert this two dimensional ArrayList into two dimensional Float array.

prophecy
  • 13
  • 2
  • `lists.stream() .flatMap(Collection::stream) .toArray(float[][]::new);` – Hadi J May 26 '20 at 13:45
  • Can you use a `Float[][]` instead of a `float[][]`? If not, your only choice is a double for loop. – Sweeper May 26 '20 at 13:46
  • 1
    [This answer](https://stackoverflow.com/a/26970398/2711488) contains a collector for a `float[]` array. Seeing it, you will likely realize that using a loop is simpler… – Holger May 26 '20 at 16:14

3 Answers3

2

First and foremost the reason why your code doesn't work is because there's no such method mapToFloat in the Java API but most importantly there is no FloatStream.

your options are quite limited if you want to accomplish this via streams:

  1. accumulate to a Float[][] instead of a float[][], which might not be ideal as it involves boxing and unboxing bottleneck when you want to perform some computation later on in your application.

this can be accomplished via:

Float[][] trainingData = lists.stream()
                .map(l -> l.toArray(new Float[0]))
                .toArray(Float[][]::new);
  1. use a List<List<Double>> in the first place rather than a List<List<Float>>to represent your training data, then you can just convert it to a double[][] when required:

this can be accomplished via:

double[][] trainingData = lists.stream()
                .map(l -> l.stream().mapToDouble(Double::doubleValue).toArray())
                .toArray(double[][]::new);

but if you cannot change the initial type of data for whatever reasons then you can still covert to a double[][].

this can be accomplished via:

double[][] trainingData = lists.stream()
                .map(l -> l.stream().mapToDouble(Float::doubleValue).toArray())
                .toArray(double[][]::new);
  1. define your own Collector which you should be able to find within the site with some research.

Ultimately you're probably better off using an imperative approach here i.e. for loops.

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
  • 1
    When you say “use a `List>` in the first place”, it’s contradicting to use `Float::doubleValue` in the example code. – Holger May 26 '20 at 16:22
  • @Holger I see where you're coming from but that piece of code was referring to _but if you cannot change the initial type of data for whatever reasons then you can still covert to a double[][]._. i'll try to clarify that. – Ousmane D. May 26 '20 at 16:24
  • 1
    So there is no example for converting `List>` to `double[][]`, actually. But when you change `Float::doubleValue` to `Number::doubleValue`, the code works regardless of whether the OP uses `List>` or `List>`… – Holger May 26 '20 at 16:27
1

Try this:

Float[][] trainingData = lists
             .stream().map(lst -> lst.stream().toArray(Float[]::new))
             .toArray(Float[][]::new);

If you need primitive arrays, the only way I can think of is what you probably already knew (but I include for completeness).

float[][] trainingData = new float[lists.size()][];

for (int i = 0; i < lists.size(); i++) {
    List<Float> innerList = lists.get(i);
    float[] temp = trainingData[i] = new float[innerList.size()];
    for (int k = 0; k < temp.length; k++) {
            temp[k] = innerList.get(k);
    }
}

for(float[] v : trainingData) {
    System.out.println(Arrays.toString(v));
}

Both print

[10.0, 10.2]
[20.4, 2.6]

WJS
  • 36,363
  • 4
  • 24
  • 39
0

For float there is no good way with stream, you can get as 2D double array this way

double[][] trainingData = lists.stream()
        .map(l -> l.stream().mapToDouble(f -> f.doubleValue()).toArray()).toArray(double[][]::new);
Eklavya
  • 17,618
  • 4
  • 28
  • 57