嗨,我有字符串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)
感谢。
答案 0 :(得分:8)
您无法在语言上将String
(引用类型)转换为int
或double
(原始数字类型)。你必须转换它们。值得庆幸的是,有一些标准的方法可以帮到你:
int Integer.parseInt(String)
double Double.parseDouble(String)
NumberFormatException
- 这可能会被parseXXX
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;
}
}
答案 2 :(得分:1)
您需要将字符串解析为double,如下所示:
double d = Double.parseDouble("45.40");
答案 3 :(得分:0)
cast
上的Object
方法会进行instanceof
测试,而您可能知道,在这种情况下会抛出ClassCastException
。你可以做的是使用Double
和Integer
的构造函数来获取String
论证。
答案 4 :(得分:0)
您可以使用Integer.parseInt和Double.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));