Я пытаюсь найти элегантный способ преобразовать 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[], чего я действительно не понимаю.
Что я делаю неправильно?
FloatStream не существует, поэтому я не думаю, что это возможно без написания специального сборщика, который конвертирует либо из Float, либо из double.
Подойдет ли double[]? Если это так, вы можете использовать Stream#mapToDouble(...) для получения DoubleStream
Почему float, а не double? Тогда вы можете использовать DoubleStream.
Дубликат - это совсем не то, что хочет OP. Во всяком случае, это - это то, что хочет OP. Но даже это не дает ответа на вопрос, почему это не работает. Голосование для открытия.
Я бы сказал, что это не дубликат. Я видел этот ответ, и это не помогло решить мою проблему.
Там есть еще один ответ. Невозможно получить таким образом примитивный float из потока.
Используйте mapToDouble(Float::parseFloat) вместе с коллектором этот ответ.




Вы можете использовать значение из объекта 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) -> IntStreammapToLong(ToLongFunction<? super T> mapper) -> LongStreammapToDouble(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[] напрямую, хотя и в коробке.
Вот использование:
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[].
Отсутствующий размер на самом деле является опечаткой в коде, который у меня есть. Я не буду исправлять вопрос, иначе ваш ответ потеряет смысл. Спасибо
Есть способ получше с моей библиотекой AbacusUtil:
float[] result = Stream.of(input).mapToFloat(Float::parseFloat).toArray();
Спасибо за то, что команда разработчиков ядра Java-библиотеки не могла сделать. Технология Single Precision удобна везде, где требуется аппаратное ускорение.
Каков тип элемента потока
input?