In this example I have tempSocket1 and tempSocket2 but I really just want one of them. I just included both to show I tried both methods, but I keep getting an error, "the method valueOf(String) in the type Integer is not applicable for the arguments (Optional)." I thought both of these methods were the ones used for converting a string data type to integer, but I'm not sure how the Optional part changes the whole system.
private void showTextInputDialog() {
TextInputDialog changePort = new TextInputDialog("Settings");
changePort.setHeaderText("Change Port");
changePort.setContentText("Please enter port number to be used for establishing connection...");
Optional<String> result = changePort.showAndWait();
result.ifPresent(e -> {
Integer tempSocket1 = Integer.valueOf(result);
Integer tempSocket2 = Integer.parseInt(result);
}
);
}
To convert an Optional to an Integer, it is necessary to invoke the get() method before the conversion.
Optional<String> cadena = Optional.of("333");
Integer num = Integer.valueOf(cadena.get());
You see, Integer.valueOf and Integer.parseInt methods need an argument of type String, but you are passing an Optional<String>. So that's why the error occurred. Optional string and string are not the same.
Just think about this, if Optional<String> were the same as String, would ArrayList<String> be the same as String? Would LinkedList<String> be the same as String? What about HashMap<String, Integer>? Would it be both a String and an Integer?
The chaos that treating generic types the same as their generic type arguments would bring is destructive! Imagine calling charAt on an optional string! Without the implementation, no one knows what will happen...
So yeah, never think that generic types are the same types as the generic type parameters.
Just to extend other answers it may looks better using map method, and even more with lambda and method reference:
Optional<String> result = changePort.showAndWait();
Integer tempSocket = result.map(Integer::valueOf).orElse(8080);
You're trying to pass an Optional<String> instead of a normal String. You need to fetch the string first with .get() before converting your result to an integer. Or use result.ifPresent(e ...) that will automatically unwrap the optional value and convert it to an Integer.
Optional<String> result = changePort.showAndWait();
result.ifPresent(e -> {
Integer tempSocket1 = Integer.valueOf(e);
Integer tempSocket2 = Integer.parseInt(e);
}
);
Related
String bob2 = "3";
System.out.println((int)bob2);
I'm unsure of why this causes an exception. Can anyone explain? Pretty sure because of the int on String type, but want to make sure.
Yes you are right its because of typecasting. If u need to convert String to int use below code
Integer.parseInt("3");
You are correct.
You can't just cast a string to an int.
You should convert it using Integer.parseInt()
Use this
Integer.valueOf("3");
or
Integer.parseInt("3");
In Java whenever you are trying to change type of an entity to another, both the types should have some relation. Like if you are trying to caste a sub class object to super class, it will work smoothly. But if you try to compare a Person object with a Lion object, that comparison is meaning less, the same is the logic in casting. We cannot cast a Person object to Lion object.
In your code bob is String type and you are trying to cast it to int and in Java both String and Integer is not having any relation. That's why Java is throwing Exception, Class Cast Exception I guess, this is raised when different types of objects are compared.
But the parseInt(String arg) method in Integer class gives an option to convert numeric String to Integer, given that the argument is a qualified Integer as per Java standards.
Example :-
String numericString = "1234";
int numberConverted = Integer.parseInt(numericString);
System.out.println(numberConverted);
You can also try these which will tell you the precautions before using this method
int numberConverted = Integer.parseInt("1234r");
int numberConverted = Integer.parseInt("1234.56");
int numberConverted = Integer.parseInt("11111111111111111111111111111");
You can't cast String to Integer. Change:
System.out.println((int)bob2);
to:
System.out.println(Integer.parseInt(bob2));
It will create an Integer value from the String provided with bob2 variable. You can also create a reference to int variable like this if you want to store primitive int instead of Integer:
int intBob2 = Integer.parseInt(bob2);
After reading through a lot of questions, I asked myself if it is possible to solve the dilemma of transforming a string into a generic number WITHOUT using a hardcoded approach.
For example: I get from a method a parameter with the type Class
With Number.isAssignableFrom or other ways I can check, if this is a number class. But I also get from the user an input. As a string.
The question is: Can I now somehow transform this string into the requested number object without building an if statement for every case?
Example code, properly not working:
Object ret = null;
for(int i=0;i<method.getParameterTypes().length; i++ ) {
Class<?> param = method.getParameterTypes()[i];
String argString = getUserInput(_in, "Argument ("+param.getSimpleName()+"): ");
if( Number.isAssignableFrom(param) )
ret = ((Class<NumberChild>)param).valueOf(argString);
/// OR
ret = param.cast( Double.valueOf(argString) )
}
The even advance this question: Could it be possible to cast every primitive in something similar in from the above way?
Note: The approach here should completely focus on a non hardcoded solution. My currently running code uses the approach of hardcoding every single case. But in those cases a more general solution would be much more interesting.
EDIT:
I'm sorry for misunderstandings, but I mean with an hardcoded approach, an approach that tests through every possible case like:
if( integer ); do ...
if( double ); do ...
if( long ); do ...
But that is exactly, what I want to work around. To clarify: This is just a challenge. My life or code is not depending on it, I just want to know IF it is possible!!
UPDATE
Since the method described in the original answer (see below) doesn't support primitives, and can only support classes which has a constructor with a single String parameter, it would be better to explicitly specify the parser method to use, for each class.
With Java 8 method references, this becomes much easier.
As you can see, even primitive values can be handled, with appropriate parse method, however the parse() method here still returns Object, so any primitive value is still boxed. That is usually the case when handling primitives through reflection.
This is a reduced example. See IDEONE for full working example.
private static HashMap<Class<?>, Function<String,?>> parser = new HashMap<>();
static {
parser.put(boolean.class , Boolean::parseBoolean); // Support boolean literals too
parser.put(int.class , Integer::parseInt);
parser.put(long.class , Long::parseLong);
parser.put(Boolean.class , Boolean::valueOf);
parser.put(Integer.class , Integer::valueOf);
parser.put(Long.class , Long::valueOf);
parser.put(Double.class , Double::valueOf);
parser.put(Float.class , Float::valueOf);
parser.put(String.class , String::valueOf); // Handle String without special test
parser.put(BigDecimal.class, BigDecimal::new);
parser.put(BigInteger.class, BigInteger::new);
parser.put(LocalDate.class , LocalDate::parse); // Java 8 time API
}
#SuppressWarnings({ "rawtypes", "unchecked" })
private static Object parse(String argString, Class param) {
Function<String,?> func = parser.get(param);
if (func != null)
return func.apply(argString);
if (param.isEnum()) // Special handling for enums
return Enum.valueOf(param, argString);
throw new UnsupportedOperationException("Cannot parse string to " + param.getName());
}
ORIGINAL ANSWER
Javadoc for Number (Java 7) lists the following "direct known subclasses", with the shown methods for parsing a single String argument:
Byte, new Byte(String s), valueOf(String s), decode(String nm)
Short, new Short(String s), valueOf(String s), decode(String nm)
Integer, new Integer(String s), valueOf(String s), decode(String nm)
Long, new Long(String s), valueOf(String s), decode(String nm)
Double, new Double(String s), valueOf(String s)
Float, new Float(String s), valueOf(String s)
BigDecimal, new BigDecimal(String val)
BigInteger, new BigInteger(String val)
AtomicInteger
AtomicLong
As you can see, you'd be best off using a constructor with a String parameter. That way would will get support for BigDecimal and BigInteger too.
Now, as for how. Use reflection. You have the Class, so ask it for the constructor, and invoke it.
Class param = /*code here*/;
String argString = /*code here*/;
Object ret;
try {
Constructor ctor = param.getConstructor(String.class);
ret = ctor.newInstance(argString);
} catch (ReflectiveOperationException e) {
throw new UnsupportedOperationException("Cannot convert string to " + param.getName());
}
This answer extends the one provided by #Andreas to take advantage of the static caches used by Integer, Short, and Byte (see this answer for details). This is possible because of the static factory method valueOf(String) provided by each of these classes. For example, by default, Integer caches all values between -128 and 127 (and this range can be extended using the -XX:AutoBoxCacheMax JVM option).
public static Number asNumber(String str,
Class<? extends Number> param) throws UnsupportedOperationException {
try {
/*
* Try to access the staticFactory method for:
* Byte, Short, Integer, Long, Double, and Float
*/
Method m = param.getMethod("valueOf", String.class);
Object o = m.invoke(param, str);
return param.cast(o);
} catch (NoSuchMethodException e1) {
/* Try to access the constructor for BigDecimal or BigInteger*/
try {
Constructor<? extends Number> ctor = param
.getConstructor(String.class);
return ctor.newInstance(str);
} catch (ReflectiveOperationException e2) {
/* AtomicInteger and AtomicLong not supported */
throw new UnsupportedOperationException(
"Cannot convert string to " + param.getName());
}
} catch (ReflectiveOperationException e2) {
throw new UnsupportedOperationException("Cannot convert string to "
+ param.getName());
}
}
Using reflection (example), try all known implementations of Number (Double, Integer, etc.) present in your classpath.
For each one, try the static method valueOf(String) and the String constructor (none are in the Number interface).
For each Number instance, make sure you can get a String representation equivalent to the user input. Otherwise you could get integer overflows.
Why does this program return error: incompatible types: int cannot be converted to String ?
public class StringConcatenation{
public static void main(String []args){
int[] testing = {0,1,3,4,5,6};
String mark = "";
for(int i=0;i<testing.length;i++)
{
// mark += testing[i]; But this line works fine
mark = testing[i]; /* This line doesn't work */
}
System.out.println(mark);
}
}
StringConcatenation.java:8: error: incompatible types: int cannot be converted to String
mark = testing[i];
The first way uses string concatenation, which is special cased in the Java language to allow you to use any object or primitive type. However, you cannot just assign a random value to a String.
The + operator can handle a string and an integer, converting the integer to string before concatenating. But you can't assign an integer to a string. Has nothing to do with using an array.
The operation += which translates to addition over its current value, converts integer to string and then concatenates it to the current state of string. However when you try to assign an integer value to a reference which is of type string, compiler will throw an error.
There are languages that will do even this for you, but it just does not work like that in a strongly typed language like java.
Here's the situation, I have an Object in a Map which I explicitly know to contain an instance of Long and I need to turn that value into a string but keep getting incompatible type errors. Here's what my code looks like:
Map<String, Object> map = ...;
Object obj = new Long(31415L);
String str = Long.valueOf((long)map.get("id")); //Problem line
This gives:
Inconvertible types.
Found : java.lang.Object
Required: long
Any suggestions as to how to get around this?
You can just do
String str = map.get("id").toString();
Use, for instance:
String.valueOf(map.get("id"))
The problem is that you try and cast an object to a primitive type. That cannot work.
But since the values of your map will be Longs anyway (collections cannot contain primitive types, save for specialized implementations such as found in GNU Trove), look at #BheshGurung's answer...
You can use the toString function;
public String toString() {
return String.valueOf(map.get("id"))
}
String str = map.get("id").toString();
You have 2 issues here:
You created a *L*ong, not a *l*ong. Therefore you need to cast back to a *L*ong, not a *l*ong.
In order to get the String representation of a *L*ong you must call toString() on it.
Use this:
String str = ((Long)map.get("id")).toString();
I am using reflection in java.
I am getting to know the type of method parameter I am passing at run time. So I am fetching the parameter value from file into a string variable.
SO now if i get to know that the parameter type as integer and if i pass an object containting the string value I am getting
argument type mismatch
java.lang.IllegalArgumentException: argument type mismatch
Class classDefinition = Class.forName("webservices."+objectName);
String methodName = set"+fieldNameAttay[i].substring(0,1)).toUpperCase()+fieldNameAttay[i].substring(1); Field f = classDefinition.getDeclaredField(fieldNameAttay[i]);
try
{
//argType = f.getType();
Method meth = classDefinition.getMethod(methodName,f.getType());
Object arg = new Object[]{fieldValueArray[i]}; //fieldValueArray[i] is always string array
meth.invoke(object, arg); //If f.getType is Integer this //throws ex
}
catch (Exception e)
{
System.err.println(e.getMessage());
e.printStackTrace();
}
You can't cast a string to an integer - you can parse it though. For example:
if (parameterType == int.class && argumentType == String.class)
{
int integerArgument = Integer.parseInt((String) argumentValue);
// Now call the method appropriately
}
Of course, you also need to consider Integer as well as int.
How about
Integer.parseInt((String) stringObj)
Note that casting can happen only if the two objects belong in the same hierarchy. So this is not casting.
If the only types you are using are String and Integer, checking the type and then using Integer.parseInt might be the simplest thing to do.
However if you have more different types, I would suggest checking out the good old JavaBeans framwork: http://download.oracle.com/javase/tutorial/javabeans/index.html
And especially the PropertyEditors
http://download.oracle.com/javase/7/docs/api/java/beans/PropertyEditor.html
http://download.oracle.com/javase/7/docs/api/java/beans/PropertyEditorManager.html
The PropertyEditors allow you to set the value as text, and then retrieve the value as correct type. Assuming you have implemented and registered the property editors, the steps to get the correct type are similer to this:
Find out the type of the parameter
Retrieve a PropertyEditor for that type
Use setAsText and getValue in the property editor to convert the value to correct type
...or You can just adapt the same mechanism to your simple needs by implementing your own conversion framework with similar but simpler interfaces.
System.out.println(Integer.parseInt(obj.toString()))
There's another way to do it:
Integer number = Integer.valueOf("1");