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

时间:2010-05-17 03:49:30

标签: java

嗨,我有字符串Map值。

我想在运行时转换此值。

e.g。

Map map = new HashMap();
map.put("key1","101");
map.put("key2","45.40");

现在运行时我知道key1是整数而key2是double 我怎么能这样做。

我试过了:

("101").getClass().cast(Integer).

////////////////////////////////////////////// 例如...........

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

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

感谢。

8 个答案:

答案 0 :(得分:8)

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

API链接

注意

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


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

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

相关问题


基于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()
            );
        }
    }
}

这会产生:

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

这不是最强大的(例如它不处理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"       
    }
}

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

答案 1 :(得分:2)

我遇到了类似的问题,并使用Apache Commons Project中的GenericValidator Helper类来解决它,以找出我认为字符串中的数据类型然后解析它。

public Object parseString(String myString) {

        if (GenericValidator.isLong(myString)) {
            return Long.parseLong(myString);
        } else if (GenericValidator.isDouble(myString)) {
            return Double.parseDouble(myString);
        } else if (GenericValidator.isDate(myString, Locale.GERMAN)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("DD.MM.YYYY");
            return  LocalDate.parse(myString, formatter);
        } else {
            return myString;
        }
}

https://commons.apache.org/proper/commons-validator/

答案 2 :(得分:1)

您需要将字符串解析为double,如下所示:

double d = Double.parseDouble("45.40");

答案 3 :(得分:0)

cast上的Object方法会进行instanceof测试,而您可能知道,在这种情况下会抛出ClassCastException。你可以做的是使用DoubleInteger的构造函数来获取String论证。

答案 4 :(得分:0)

您可以使用Integer.parseIntDouble.parseDouble

int value1 = Integer.parseInt(map.get("key1"));
double value2 = Double.parseDouble(map.get("key2"));

答案 5 :(得分:0)

你不能施放 String到任何其他类型,你必须转换它。例如,要转换为Integer

Integer value = Integer.valueOf(string);

Double

Double value = Double.valueOf(string);

答案 6 :(得分:0)

好的,在阅读了其他评论之后,我认为你是在追求这样的事情:

static Number convertNumber(String className, String value)
  throws NoSuchMethodException, InvocationTargetException, 
    IllegalArgumentException, IllegalAccessException, ClassNotFoundException {
  Class<?> clazz = Class.forName(className);
  Method method = clazz.getDeclaredMethod("valueOf", String.class);
  return (Number)method.invoke(clazz, value);
}

您可以这样使用:

Map<String, String> map1 = new HashMap<String, String>();
Map<String, String> map2 = new HashMap<String, String>();
map1.put("key1", "java.lang.Integer");
map2.put("key1","101");
map1.put("key2", "java.lang.Double");
map2.put("key2","45.40");

try {
  Number value;
  value = convertNumber(map1.get("key1"), map2.get("key1"));
  System.out.format("Value = %s, type = %s\n", value, value.getClass().getSimpleName());
  value = convertNumber(map1.get("key2"), map2.get("key2"));
  System.out.format("Value = %s, type = %s\n", value, value.getClass().getSimpleName());
  value = convertNumber("java.lang.Integer", "foo!");
  System.out.format("Value = %s, type = %s\n", value, value.getClass().getSimpleName());
} catch (Exception e) {
  e.printStackTrace(System.out);
}

答案 7 :(得分:0)

如果我正确理解您的问题,我认为您可以使用Java Reflection创建新对象。调用构造函数等同于创建新对象。

  

Map<Integer, String> typeMap = new HashMap<Integer, String>();

     

Map<Integer, String> valueMap = new HashMap<Integer, String>();

     

typeMap.put(1, "java.lang.Double");

     

valueMap.put(1, "10");

     

Class clazz = Class.forName((String) typeMap.get(1));

     

Constructor constructor = clazz.getConstructor(String.class);

     

Object obj = constructor.newInstance(valueMap.get(1));