Преобразование потока строк Java в массив с плавающей запятой

Я пытаюсь найти элегантный способ преобразовать Java Stream<String> в массив с плавающей запятой. До сих пор я писал:

Float[] data = input.map(Float::valueOf).toArray(Float[]::new);

Но мне действительно нужен float[], и когда я пытаюсь:

float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[]);

Я получаю сообщение об ошибке: не могу преобразовать Object[] в float[], чего я действительно не понимаю.

Что я делаю неправильно?

Каков тип элемента потока input?

ernest_k 22.06.2018 18:44

FloatStream не существует, поэтому я не думаю, что это возможно без написания специального сборщика, который конвертирует либо из Float, либо из double.

Radiodef 22.06.2018 18:46

Подойдет ли double[]? Если это так, вы можете использовать Stream#mapToDouble(...) для получения DoubleStream

Turing85 22.06.2018 18:46

Почему float, а не double? Тогда вы можете использовать DoubleStream.

daniu 22.06.2018 18:46

Дубликат - это совсем не то, что хочет OP. Во всяком случае, это - это то, что хочет OP. Но даже это не дает ответа на вопрос, почему это не работает. Голосование для открытия.

Turing85 22.06.2018 18:55

Я бы сказал, что это не дубликат. Я видел этот ответ, и это не помогло решить мою проблему.

Gianluca 22.06.2018 19:13

Там есть еще один ответ. Невозможно получить таким образом примитивный float из потока.

Makoto 22.06.2018 19:19

Используйте mapToDouble(Float::parseFloat) вместе с коллектором этот ответ.

Holger 25.06.2018 16:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
8
3 609
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете использовать значение из объекта Float через метод floatValue () для создания массива:

Float[] data = input.map(Float::valueOf).toArray(Float[]::new);
float[] primData = new float[data.length];

for(int x = 0; x < data.length; x ++) {
    primData[x] = data[x].floatValue();
}

Еще есть ни за что получения float[] напрямую из любого потока в Java. Есть «всего» 3 доступных механизма преобразования в числовые потоковые интерфейсы:

  • mapToInt(ToIntFunction<? super T> mapper) -> IntStream
  • mapToLong(ToLongFunction<? super T> mapper) -> LongStream
  • mapToDouble(ToDoubleFunction<? super T> mapper) -> DoubleStream

Таким образом, единственный способ - использовать вместо него double, что довольно просто:

double[] data = input.mapToDouble(Double::parseDouble).toArray();

Если вы настаиваете на получении float[] от double[], это еще одна проблема, в которой может помочь библиотека Guava:

float[] floatArray = Floats.toArray(Doubles.asList(data));
// You can collect Stream to a Collection and pass directly Floats.toArray(list);

Или простой for-loop:

float[] floatArray = new float[data.length];
for (int i = 0 ; i < data.length; i++) {
    floatArray[i] = (float) data[i];
}

В качестве альтернативы вы можете использовать метод toArray(IntFunction<A[]> generator), который возвращает массив типа Object. Однако, чтобы распаковать Float, вы должны снова использовать цикл for точно так же - это не дает никакой разницы, за исключением того, что вы можете работать с Float[] напрямую, хотя и в коробке.

  • map(Function<? super T,? extends R> mapper) -> Stream<R>

Вот использование:

Float[] data = input.map(Float::valueOf).toArray(Float[]::new);
Ответ принят как подходящий

В вашем коде есть небольшая ошибка, которую мы исправим в первую очередь, чтобы выявить более серьезную проблему:

float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[]);

должно быть:

float[] data = input.map(x -> Float.parseFloat(x)).toArray(size -> new float[size]);
                                                                             ^this is new

Даже если может показаться, что это не так, ваш вопрос относится к дженерикам. Давайте посмотрим на определение Stream#toArray(...):

public <A> A[] toArray​(IntFunction<A[]> generator)

Поскольку этот метод является общим для A, тип A не должен быть примитивом. Вы, с другой стороны, пытаетесь установить A на float (это делается через вывод типа, поэтому вы не видите общие параметры в вашем коде). Теперь компилятор жалуется, что:

error: incompatible types: inference variable A has incompatible bounds
    float[] data = input.stream().map(x -> Float.parseFloat(x)).toArray(size -> new float[size]);
                                                                       ^
    equality constraints: float
    upper bounds: Object
  where A is a type-variable:
    A extends Object declared in method <A>toArray(IntFunction<A[]>)
1 error

Этот вопрос и ответ на него предоставляет решения / обходные пути проблемы преобразования потока String в float[].

Отсутствующий размер на самом деле является опечаткой в ​​коде, который у меня есть. Я не буду исправлять вопрос, иначе ваш ответ потеряет смысл. Спасибо

Gianluca 22.06.2018 22:56

Есть способ получше с моей библиотекой AbacusUtil:

float[] result = Stream.of(input).mapToFloat(Float::parseFloat).toArray();

Спасибо за то, что команда разработчиков ядра Java-библиотеки не могла сделать. Технология Single Precision удобна везде, где требуется аппаратное ускорение.

Akumaburn 04.12.2020 02:51

Другие вопросы по теме