[英]Convert a double array to a float array
我有一個 double[][] 數組,我想將一行放入 float[] 數組。 鑄造起初不起作用,所以我尋找不同的東西。
我在 stackoverflow 中找到了一個將 Object[] 轉換為 String[] 的優雅解決方案,如果我將 Object[] 轉換為 float[],它也可以工作。
那么:有沒有什么優雅的方法可以將 double[] 轉換為 float[],或者將 double[] 轉換為 Object[],這樣我就可以在另一篇文章中使用代碼了?
我將提供我正在做的示例代碼,即使我認為這不是必需的:
double[][] datos = serie.toArray();
double[][] testArray = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}};
double[] doubleArray = Arrays.copyOf(testArray[1], testArray[1].length);
// This would be great but doesn't exist:
//float[] floatArray = Arrays.copyOf(doubleArray, doubleArray.length, float[].class);
不,投射數組不起作用。 您需要顯式轉換每個項目:
float[] floatArray = new float[doubleArray.length];
for (int i = 0 ; i < doubleArray.length; i++)
{
floatArray[i] = (float) doubleArray[i];
}
這是一個您可以放置在庫中並反復使用的函數:
float[] toFloatArray(double[] arr) {
if (arr == null) return null;
int n = arr.length;
float[] ret = new float[n];
for (int i = 0; i < n; i++) {
ret[i] = (float)arr[i];
}
return ret;
}
備查; 這也可以通過使用 Guava 更簡潔地完成,如下所示:
double[] values = new double[]{1,2,3};
float[] floatValues = Floats.toArray(Doubles.asList(values));
使用 Kotlin,您可以嘗試以下操作:
val doubleArray = arrayOf(2.0, 3.0, 5.0)
val floatArray = doubleArray.map { it.toFloat() }.toFloatArray()
要么
val floatArray = arrayOf(2.0, 3.0, 5.0).map { it.toFloat() }.toFloatArray()
我創建了這個類供我個人使用,但我認為它可以幫助您解決問題。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class ArrayUtils {
private static final Logger log = LoggerFactory.getLogger(ArrayUtils.class);
private static final Map<Class, Class> primitiveMapping = new HashMap<Class, Class>();
private static final Map<Class, Method> primitiveParseMethodLookup = new HashMap<Class, Method>();
private static final Map<Class, Method> primitiveArrayGetMethodLookup = new HashMap<Class, Method>();
private static final Map<Class, Method> valueOfMethodLookup = new HashMap<Class, Method>();
static {
// Initialize primitive mappings
primitiveMapping.put(boolean.class, Boolean.class);
primitiveMapping.put(byte.class, Byte.class);
primitiveMapping.put(short.class, Short.class);
primitiveMapping.put(int.class, Integer.class);
primitiveMapping.put(float.class, Float.class);
primitiveMapping.put(long.class, Long.class);
primitiveMapping.put(double.class, Double.class);
// Initialize parse, valueOf and get method lookup
// We do that in advance because the lookup of the method takes the longest time
// Compared to the normal method call it's 20x higher
// So we use just the reflective method call which takes double the time of a normal method call
try {
primitiveParseMethodLookup.put(boolean.class, Boolean.class.getMethod("parseBoolean", new Class[]{String.class}));
primitiveParseMethodLookup.put(byte.class, Byte.class.getMethod("parseByte", new Class[]{String.class}));
primitiveParseMethodLookup.put(short.class, Short.class.getMethod("parseShort", new Class[]{String.class}));
primitiveParseMethodLookup.put(int.class, Integer.class.getMethod("parseInt", String.class));
primitiveParseMethodLookup.put(float.class, Float.class.getMethod("parseFloat", String.class));
primitiveParseMethodLookup.put(long.class, Long.class.getMethod("parseLong", String.class));
primitiveParseMethodLookup.put(double.class, Double.class.getMethod("parseDouble", String.class));
valueOfMethodLookup.put(Boolean.class, Boolean.class.getMethod("valueOf", new Class[]{String.class}));
valueOfMethodLookup.put(Byte.class, Byte.class.getMethod("valueOf", new Class[]{String.class}));
valueOfMethodLookup.put(Short.class, Short.class.getMethod("valueOf", new Class[]{String.class}));
valueOfMethodLookup.put(Integer.class, Integer.class.getMethod("valueOf", String.class));
valueOfMethodLookup.put(Float.class, Float.class.getMethod("valueOf", String.class));
valueOfMethodLookup.put(Long.class, Long.class.getMethod("valueOf", String.class));
valueOfMethodLookup.put(Double.class, Double.class.getMethod("valueOf", String.class));
primitiveArrayGetMethodLookup.put(boolean.class, Array.class.getMethod("getBoolean", new Class[]{Object.class, int.class}));
primitiveArrayGetMethodLookup.put(byte.class, Array.class.getMethod("getByte", new Class[]{Object.class, int.class}));
primitiveArrayGetMethodLookup.put(short.class, Array.class.getMethod("getShort", new Class[]{Object.class, int.class}));
primitiveArrayGetMethodLookup.put(int.class, Array.class.getMethod("getInt", Object.class, int.class));
primitiveArrayGetMethodLookup.put(float.class, Array.class.getMethod("getFloat", Object.class, int.class));
primitiveArrayGetMethodLookup.put(long.class, Array.class.getMethod("getLong", Object.class, int.class));
primitiveArrayGetMethodLookup.put(double.class, Array.class.getMethod("getDouble", Object.class, int.class));
} catch (NoSuchMethodException e) {
//******************************
// This can never happen
//******************************
}
}
public static boolean isArrayOfPrimitives(Object object) {
if (object.getClass().isArray()) {
return object.getClass().getComponentType().isPrimitive();
}
return false;
}
public static boolean isArrayOf(Object object, Class clazz) {
if (object.getClass().isArray()) {
return clazz.isAssignableFrom(object.getClass().getComponentType());
}
return false;
}
/**
* Convert any array of primitives(excluding char), strings or numbers into any other array
* of strings or numbers.
*
* @param array Array of primitives(excluding char), strings or numbers
* @param convertedArrayComponentType Converted array component type (String or Number)
* @param <T> To allow implicit casting
* @return Array of convertedArrayComponentType
*/
public static <T> T[] convertArray(Object array, Class<T> convertedArrayComponentType) {
// Collect data regarding arguments
final boolean arrayOfPrimitives = isArrayOfPrimitives(array);
final boolean arrayOfCharPrimitives = isArrayOf(array, char.class);
final boolean arrayOfCharacters = isArrayOf(array, Character.class);
final boolean arrayOfStrings = isArrayOf(array, String.class);
final boolean arrayOfNumbers = isArrayOf(array, Number.class);
// Check if array is an array of strings, primitives or wrapped primitives
if (!arrayOfPrimitives && !arrayOfNumbers && !arrayOfStrings || arrayOfCharPrimitives || arrayOfCharacters) {
throw new IllegalArgumentException(array + " must be an array of of strings, primitives or boxed primitives (byte, boolean, short, int, float, long, double)");
}
// Check if it's assignable from Number of String
if (!Number.class.isAssignableFrom(convertedArrayComponentType) && !String.class.isAssignableFrom(convertedArrayComponentType)) {
throw new IllegalArgumentException(convertedArrayComponentType + " must be a Number or a String");
}
try {
return (T[]) convertArrayInternal(array, convertedArrayComponentType);
} catch (InvocationTargetException e) {
// This can happen due to errors in conversion
throw (RuntimeException) e.getTargetException();
} catch (Exception e) {
// This should never happen
log.error("Something went really wrong in ArrayUtils.convertArray method.", e);
}
// To satisfy the compiler
return null;
}
/**
* Convert any array of primitives(excluding char), strings or numbers into an array
* of primitives(excluding char).
*
* @param array Array of primitives(excluding char), strings or numbers
* @param convertedArrayComponentType Converted array component type primitive(excluding char)
* @return Array of convertedArrayComponentType
*/
public static Object convertToPrimitiveArray(Object array, Class convertedArrayComponentType) {
// Collect data regarding arguments
final boolean arrayOfPrimitives = isArrayOfPrimitives(array);
final boolean arrayOfCharPrimitives = isArrayOf(array, char.class);
final boolean arrayOfCharacters = isArrayOf(array, Character.class);
final boolean arrayOfStrings = isArrayOf(array, String.class);
final boolean arrayOfNumbers = isArrayOf(array, Number.class);
// Check if array is an array of strings, primitives or wrapped primitives
if (!arrayOfPrimitives && !arrayOfNumbers && !arrayOfStrings || arrayOfCharPrimitives || arrayOfCharacters) {
throw new IllegalArgumentException(array + " must be an array of of strings, primitives or boxed primitives (byte, boolean, short, int, float, long, double)");
}
// Check if it's assignable from Number of String
if (!convertedArrayComponentType.isPrimitive() || convertedArrayComponentType.isAssignableFrom(char.class)) {
throw new IllegalArgumentException(convertedArrayComponentType + " must be a primitive(excluding char)");
}
try {
return convertArrayInternal(array, convertedArrayComponentType);
} catch (InvocationTargetException e) {
// This can happen due to errors in conversion
throw (RuntimeException) e.getTargetException();
} catch (Exception e) {
// This should never happen
log.error("Something went really wrong in ArrayUtils.convertArray method.", e);
}
// To satisfy the compiler
return null;
}
private static Object convertArrayInternal(Object array, Class convertedArrayComponentType) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// Lookup the primitive parse method or the boxed primitive valueOf method
final Method convertMethod;
if (convertedArrayComponentType.isPrimitive()) {
convertMethod = primitiveParseMethodLookup.get(convertedArrayComponentType);
} else {
convertMethod = valueOfMethodLookup.get(convertedArrayComponentType);
}
// If the array is an array of primitives lookup the get method
final Method primitiveArrayGetMethod = primitiveArrayGetMethodLookup.get(array.getClass().getComponentType());
// Get length and create new array
final int arrayLength = Array.getLength(array);
final Object castedArray = Array.newInstance(convertedArrayComponentType, arrayLength);
for (int i = 0; i < arrayLength; i++) {
final Object value;
if (primitiveArrayGetMethod != null) {
value = primitiveArrayGetMethod.invoke(null, array, i);
} else {
value = Array.get(array, i);
}
final String stringValue = String.valueOf(value);
final Object castedValue = convertMethod.invoke(null, stringValue);
Array.set(castedArray, i, castedValue);
}
return castedArray;
}
}
它可以像這樣使用:
double[][] testArray = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}};
double[] doubleArray = Arrays.copyOf(testArray[1], testArray[1].length);
float[] floatArray = (float[]) ArrayUtils.convertToPrimitiveArray(doubleArray, float.class);
我對此很納悶。 可以嗎? 這是我遇到的類似問題:
int[][] exampleIntPoints = new int[][]{
{1, 5, 2}, {1, 2, 3}, {2, 0, 1}, // etc...
}
int[] i = new int[1];
float[] floatPoints = new float[exampleIntPoints.length * 3];
Arrays.stream(exampleIntPoints)
.map(intPoint -> new Point3D(intPoint[0], intPoint[1], intPoint[2]))
.map(Point3D::normalize)
.map(p -> DoubleStream.of(p.getX(), p.getY(), p.getZ()))
.reduce(DoubleStream.empty(), DoubleStream::concat)
.forEach(d -> floatPoints[i[0]++] = (float) d);
如果這是錯誤的話,我確實想知道為什么...我認為這段代碼可以實現而無需創建多余的數據結構。 是的,我知道這很懶,但這就是流init!
斯威夫特 5
extension Collection where Iterator.Element == Float
{
var convertToDouble: [Double]
{
return compactMap { Double($0) }
}
}
extension Collection where Iterator.Element == Double
{
var convertToFloat: [Float]
{
return compactMap { Float($0) }
}
}
Kotlin
val doubleArray = arrayOf(2.0, 3.0, 5.0)
val floatArray = FloatArray(doubleArray.size) { i -> doubleArray[i].toFloat() }
在一行中使用“ forEach”方法的另一種解決方案:
myarray = ['3','5','6'];
myarray.forEach(function (item){var ind = myarray.indexOf(item); myarray[ind] = parseFloat(item)});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.