Преобразование двумерного массива ArrayList в двумерный массив с плавающей запятой - PullRequest
1 голос
/ 26 мая 2020
ArrayList<ArrayList<Float>> lists = new ArrayList<ArrayList<Float>>();

Это Arraylist, который я использую. И я пробовал это:

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

Я получаю эту ошибку:

Метод mapToFloat (Float :: parseFloat) не определен для типа Stream

Я должен преобразовать этот двумерный ArrayList в двумерный массив с плавающей запятой.

Ответы [ 3 ]

2 голосов
/ 26 мая 2020

В первую очередь причина, по которой ваш код не работает, заключается в том, что такого метода mapToFloat в Java API нет, но, что наиболее важно, нет FloatStream.

ваши варианты вполне ограничено, если вы хотите выполнить sh это через потоки:

  1. накапливается в Float[][] вместо float[][], что может быть не идеально, поскольку оно включает узкое место упаковки и распаковки, когда вы хотите для выполнения некоторых вычислений позже в вашем приложении.

это можно сделать с помощью:

Float[][] trainingData = lists.stream()
                .map(l -> l.toArray(new Float[0]))
                .toArray(Float[][]::new);
используйте в первую очередь List<List<Double>>, а не List<List<Float>> для представления ваших тренировочных данных, затем вы можете просто преобразовать его в double[][], когда это необходимо:

это может быть выполняется с помощью:

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

, но если вы не можете изменить исходный тип данных по каким-либо причинам, вы все равно можете скрыть его до double[][].

, это может быть выполнено с помощью:

double[][] trainingData = lists.stream()
                .map(l -> l.stream().mapToDouble(Float::doubleValue).toArray())
                .toArray(double[][]::new);
определите свой собственный Collector, который вы сможете найти на сайте после некоторого исследования.

В конечном итоге вам, вероятно, лучше использовать здесь императивный подход т.е. for петель.

1 голос
/ 26 мая 2020

Для float нет хорошего способа с потоком, вы можете получить как двумерный двойной массив таким образом

double[][] trainingData = lists.stream()
        .map(l -> l.stream().mapToDouble(f -> f.doubleValue()).toArray()).toArray(double[][]::new);
1 голос
/ 26 мая 2020

Попробуйте следующее:

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

Если вам нужны примитивные массивы, я могу думать только о том, что вы, вероятно, уже знали (но я включаю для полноты).

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));
}

Оба печатают

[10.0, 10.2]
[20.4, 2.6]

...