运行时从String转换为其他数据类型

Gen*_*lin 5 java

嗨我有字符串值的Map.

我想在运行时强制转换此值.

例如

Map map = new HashMap();
map.put("key1","101");
map.put("key2","45.40");
Run Code Online (Sandbox Code Playgroud)

现在运行时我知道key1是整数而key2是double我该如何转换它.

我试过这个:

("101").getClass().cast(Integer).
Run Code Online (Sandbox Code Playgroud)

////////////////////////////////////////////// ........

String integerClass ="java.lang.Integer"; String strNum ="5"; 现在,您将如何使用integerClass将此strNum值"5"转换为Integer.

.....不直接使用新的Integer(strNum)

谢谢.

pol*_*nts 8

您无法在语言上将String(引用类型)转换为intdouble(原始数字类型).你必须转换它们.值得庆幸的是,有一些标准的方法可以帮到你:

API链接

注意

T Class<T>.cast(Object)做了完全不同的事情.它与泛型,反射,类型标记等有关.


也就是说,我注意到你使用的是原始Map类型.由于这看起来像一个新代码,应该说你不应该在新代码中使用原始类型.您可能永远不需要从一String开始就转换为int/ double(或者至少将它们放入地图之前进行转换).

A Map<String,Number>(或者可能是a Map<String,Double>)会更好,因为地图是"类型安全的"; 你知道它映射StringNumber,并且编译器将确保你没有做任何违反这种类型不变量的事情.

相关问题


基于OP的评论,看起来像这样的东西是期望的:

import java.util.*;
public class MapTranslate {
    static Object interpret(String s) {
        Scanner sc = new Scanner(s);
        return
            sc.hasNextInt() ? sc.nextInt() :
            sc.hasNextLong() ? sc.nextLong() :
            sc.hasNextDouble() ? sc.nextDouble() :
            sc.hasNext() ? sc.next() :
            s;
    }
    public static void main(String[] args) {
        Map<String,String> map1 = new HashMap<String,String>();
        map1.put("One", "1");
        map1.put("PI", "3.141592653589793");
        map1.put("10^12", "1000000000000");
        map1.put("Infinity", "oo");
        map1.put("Blank", "   ");

        Map<String,Object> map2 = new HashMap<String,Object>();
        for (Map.Entry<String,String> entry : map1.entrySet()) {
            map2.put(entry.getKey(), interpret(entry.getValue()));
        }

        for (Map.Entry<String,Object> entry: map2.entrySet()) {
            System.out.format("%s->[%s] (%s)%n",
                entry.getKey(),
                entry.getValue(),
                entry.getValue().getClass().getSimpleName()
            );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这会产生:

PI->[3.141592653589793] (Double)
Infinity->[oo] (String)
One->[1] (Integer)
10^12->[1000000000000] (Long)
Blank->[   ] (String)
Run Code Online (Sandbox Code Playgroud)

这不是最强大的(例如它不处理null键/值),但它可能是一个很好的起点.注意它使用java.util.Scanner及其hasXXX方法; 这样你就不用担心了NumberFormatException.

但是,如果不了解大局,就很难评论这样的事情是否是一个好主意.

相关问题


用反射

这似乎也是问题的一个方面; 以下内容应具有指导意义:

import java.lang.reflect.*;

public class ValueOfString {
    static <T> T valueOf(Class<T> klazz, String arg) {
        Exception cause = null;
        T ret = null;
        try {
            ret = klazz.cast(
                klazz.getDeclaredMethod("valueOf", String.class)
                .invoke(null, arg)
            );
        } catch (NoSuchMethodException e) {
            cause = e;
        } catch (IllegalAccessException e) {
            cause = e;
        } catch (InvocationTargetException e) {
            cause = e;
        }
        if (cause == null) {
            return ret;
        } else {
            throw new IllegalArgumentException(cause);
        }
    }
    public static void main(String[] args) throws ClassNotFoundException {
        Integer ii = valueOf(Integer.class, "42"); // no need to cast!
        System.out.println(ii); // prints "42"

        Object o = valueOf(Class.forName("java.lang.Double"), "3.14159");
        System.out.println(o);
        System.out.println(o instanceof Double); // prints "true"       
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码片段使用类型标记和反射来调用static valueOf(String)方法.然而,在这种情况下使用反射可能是不合理的,并且仅仅明确地检查期望的转换是什么可能更好,例如"java.lang.Integer",然后相应地调用Integer.valueOf.


SLa*_*aks 1

您需要将字符串解析为双精度型,如下所示:

double d = Double.parseDouble("45.40");
Run Code Online (Sandbox Code Playgroud)