【问题标题】:Convert a double array to a float array将双精度数组转换为浮点数组
【发布时间】:2011-11-22 17:28:41
【问题描述】:

我有一个 double[][] 数组,我想将一行放入 float[] 数组。一开始铸造没有效果,所以我寻找不同的东西。

我发现here in 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);

【问题讨论】:

    标签: java arrays floating-point double


    【解决方案1】:

    不,强制转换数组不起作用。您需要显式转换每个项目:

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

    【讨论】:

      【解决方案2】:

      这是一个您可以放在库中并反复使用的函数:

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

      【讨论】:

      • 使用 System.arrayCopy
      【解决方案3】:

      供日后参考;这也可以通过使用 Guava 更简洁地完成,如下所示:

      double[] values = new double[]{1,2,3};
      
      float[] floatValues = Floats.toArray(Doubles.asList(values));
      

      【讨论】:

      • 看起来真的很慢(可能不是,只是说它看起来很慢)。你有没有机会测试过这个?
      • 不,我没有测试运行时间。它可能不如编写循环快,但如果您不经常这样做和/或对于大型列表,它仍然不应该花费很多时间。
      • 好的,所以我测试了它。它在我的机器上慢了 9 倍。 pastebin.com/Rh5eWY7q恕我直言,这不应该被使用。它只是少了一行、更慢、更复杂,并且需要巨大的依赖。
      • 感谢您努力测试性能。我同意仅仅为此包含 Guava 有点过头了,但如果你已经在使用它,我认为这比循环更清晰。不是因为它节省了两行(不是一行),而是因为它节省了循环本身。这当然是主观的,但在我看来,循环通常表示复杂性,在阅读代码时值得关注。这就是为什么我更喜欢我发布的sn-p。正如我所解释的,我通常不会真正关心这样一个函数的性能,我不同意这比循环更复杂。
      【解决方案4】:

      使用 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()
      

      【讨论】:

        【解决方案5】:

        我创建了这个类供我个人使用,但我认为它可以帮助你解决问题。

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

        【讨论】:

          猜你喜欢
          • 2015-06-12
          • 1970-01-01
          • 2011-01-02
          • 2018-04-26
          • 1970-01-01
          • 2011-07-07
          • 1970-01-01
          • 2018-08-09
          • 2014-12-09
          相关资源
          最近更新 更多