You can't linguistically cast a String
(a reference type) to an int
or a double
(a primitive numeric type). You'd have to convert them. Thankfully, there are standard methods to do them for you:
API links
Note
T Class<T>.cast(Object)
does something entirely different. It has to do with generics, reflection, type-tokens, etc.
That said, I noticed that you used a raw Map
type. Since this looks like a new code, it should be said that you should NOT use raw types in new code. It's possible that you may never need to convert from String
to int
/double
in the first place (or at least do it BEFORE you put them into the map).
A Map<String,Number>
(or perhaps a Map<String,Double>
) would be better, because the map is "type-safe"; you know it maps String
to Number
, and the compiler would ensure that you're not doing anything to violate this type invariant.
Related questions
Based on OP's comments, it looks like something like this was desired:
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()
);
}
}
}
This produces:
PI->[3.141592653589793] (Double)
Infinity->[oo] (String)
One->[1] (Integer)
10^12->[1000000000000] (Long)
Blank->[ ] (String)
This is not the most robust (e.g. it doesn't handle null
keys/values), but it may be a good starting point. Note that it uses java.util.Scanner
and its hasXXX
methods; this way you don't have to worry about any NumberFormatException
.
Without understanding the big picture, though, it's hard to comment whether something like this is even a good idea to begin with.
Related questions
Using reflection
This seems to also be an aspect of the question; the following should be instructive:
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"
}
}
The above snippet uses type tokens and reflections to invoke static valueOf(String)
method. The use of reflection may not be justifiable in this case, however, and it may simply be better to just explicitly check what the desired conversion is, e.g. "java.lang.Integer"
, and then invoke Integer.valueOf
accordingly.