Conversion between numeric objects in Java - java

I am looking for a simple, concise way to convert a given Number object to an object of a given numeric type.
Loss of precision due to narrowing conversions is fine
I prefer not to go through strings.
I need something like:
private static Number convert(Number num, Class<? extends Number> targetType)
Is there a way to do it without checking all the combinations of types?

I think the clearest way is to use brute force:
private static Number convert(Number num, Class<? extends Number> targetType) {
Number result = null;
if (Byte.class.equals(targetType)) {
result = Byte.valueOf(num.byteValue());
} else if (Short.class.equals(targetType)) {
result = Short.valueOf(num.shortValue());
} else if (...) {
...
} else {
throw new IllegalArgumentException("targetType is not a Number");
}
return result;
}
You might use reflection, but I find that more hackish.

You can use something like:
String simpleName = targetType.getSimpleName().toLowerCase();
if (simpleName.equals("integer")) {
simpleName = "int";
}
Method m = number.getClass().getMethod(simpleName + "Value");
return (Number) m.invoke(number);
This relies on the fact that Number has methods like longValue(), floatValue(), etc.
As for BigInteger or AtomicInteger - you can use their constructor reflectively, which accepts one argument - the primitive type.

Perhaps converting via BigDecimal would work?

Related

Is there a way to create a variable that matches T argument in a generic class?

I have a generic class, let's call it Parser<T>. In the main program, I would like to create an instance of Parser where T depends on the input parameters (because there would be a lot of options).
For instance, I have a variable Class x = BigInteger.class. So that means that I want T to be BigInteger.
Is there a possible way to use my variable instead of T to get Parser<BigInteger>? If not how would you recommend to do it?
P.S. I'm new to Java and also not a native English speaker, so I understand that the question may be very silly or has already been answered, if that's the case, I'm sorry.
There is no good way to do that. Explicit or inferred type parameters have to static (compile time) types.
By the sounds of it, you may be better off with a non-generic type that takes a Class as a parameter.
If you stick with generics you will probably end up with something ugly, like this:
if (class.getName().equals("java.lang.BigInteger")) {
BigInteger i = new Parser<BigInteger>().parse(someString);
// do something with 'i'
} else if (...) {
// ad nauseum
}
It is also possible that you would be better off with the type parameter on the parse method rather than the class; e.g.
class Parser {
<T> parse(Class<T> expected, String input) {
// do parsing of input
if (expected.isInstance(result)) {
return expected.cast(result) {
} else {
// throw some exception
}
}
But even then, the caller needs a separate static call for each case if it is going to make use of the return type; e.g.
if (class.getName().equals("java.lang.BigInteger")) {
BigInteger i = parser.parse(BigInteger.class, someString);
// do something with 'i'
} else if (...) {
// ad nauseum
}
You should pass your variable to the constructor.
public class Parser<T> {
final Class<T> clazz;
public Parser(Class<T> clazz) {
this.clazz = clazz;
}
#Override
public String toString() {
return "Parser<" + clazz.getSimpleName() + ">";
}
}
and
Class a = BigInteger.class;
Parser parser1 = new Parser(a);
System.out.println(parser1);
Class b = String.class;
Parser parser2 = new Parser(b);
System.out.println(parser2);
->
Parser<BigInteger>
Parser<String>

Method to box primitive type

Here is a table of primitive types and their equivalent wrapper class.
Primitive type Wrapper class
============== =============
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double
I would like to create a method that would convert any given primitive variable into an appropriate class. I have tried something like below, but that obviously does not work. Any help would be appreciated:
public static <T> T forceBox(T t) {
switch (T) {
case boolean.class : return new Boolean(t);
case int.class : return new Integer(t);
// etc
}
}
the caller code looks like:
int x = 3;
System.out.println("x wrapper type: " + forceBox(x).getClass());
Though this is completely unnecessary in most cases, just use
public static <T> T forceBox(T t) { // compiler will add the conversion at the call site
return t;
}
Though you can also just use
Object o = <some primitive>;
The conversion is already done when needed as part of the boxing process.

Java Possible to Return Either Float or Integer?

Is it possible to have a function that returns either Integer or Float? I want to have the 2 functions become one if it's possible:
private static Integer parseStringFormatInt(String val){
System.out.println(Integer.parseInt(val.substring(0, val.indexOf("."))));
return Integer.parseInt(val.substring(0, val.indexOf(".")));
}
private static Float parseStringFormatFloat(String val){
System.out.println(Float.parseFloat(val.substring(0, val.indexOf("."))));
return Float.parseFloat(val.substring(0, val.indexOf(".")));
}
Make the return type as Number since both Float and Integer are subtypes of Number like below
private static Number parseStringFormatNumber(String val){
//Based on your conditions return either Float or Integer values
}
You can also make instanceof operator to do the test on the return value, to get the exact type of the returned value. i.e Float or Integer
if(returnedValue instanceof Float)
{
// type cast the returned Float value and make use of it
}
else if(returnedValue instanceof Integer)
{
// type cast the returned Integer value and make use of it
}
You can use Number as return type, or make the method generic
static <T extends Number> T parseString(String str, Class<T> cls) {
if (cls == Float.class) {
return (T) Float.valueOf(str);
} else if (cls == Integer.class) {
return (T) Integer.valueOf(str);
}
throw new IllegalArgumentException();
}
You can return Number:
private static Number parseStringFormatNumber(String val){
try {
return Integer.valueOf(val.substring(0, val.indexOf(".")));
} catch (NumberFormatException e) {
try {
return Float.valueOf(val.substring(0, val.indexOf(".")));
} catch (NumberFormatException e2) {
// handle invalid value (throw exception, return 0?)
}
}
}
I wouldn't. I would have the method return 'float', with a small 'f', or more probably 'double'; I would have it parse the entire value without any substring operations; and I would cast the value to 'int' at the call sites that require it, and/or from there to Integer, Float, Double, ... whatever you need at the call site.
You will find this is orders of magnitude more efficient than the answer you've accepted, which is just a poor man's self-implemented runtime polymorphism where you previously had compile-time polymorphism.
But the problem itself is highly dubious. There are no ints and floats in an Excel file. There are only decimal numbers with zero or more decimal places.
Alternatively, return a discriminated union such as Either<Integer, Float>. There is a stand-alone implementation of Either for Java 8 in a small library, "ambivalence": http://github.com/poetix/ambivalence
Either<Integer, Float> either1 = Either.ofLeft(23);
Either<Integer, Float> either2 = Either.ofRight(Float.valueOf("3.14"));
BigDecimal result1 = either1.join(BigDecimal::valueOf, BigDecimal::valueOf);
BigDecimal result2 = either2.join(BigDecimal::valueOf, BigDecimal::valueOf);
You can get it from Maven central:
<dependency>
<groupId>com.codepoetics</groupId>
<artifactId>ambivalence</artifactId>
<version>0.2</version>
</dependency>

How to avoid unsafe cast warnings with Java Generics

I'm quite new to Java Generics. But I've read a lot of summary links and examples. But I cannot get the simplest method right. I hope somenoe can help:
I want to create a HashMap which maps one undefined Object to another one. Both objects may one of String or Integer.
So I wrote this:
private final HashMap<L, R> left2Right = new HashMap<L, R>();
Extractor<?> extLeft = Extractor.getInstance(0);
Extractor<?> extRight = Extractor.getInstance(1);
L leftVal = extLeft.extract(d, i);
R rightVal = extRight.extract(d, i);
this.left2Right.put(leftVal, rightVal);
So far so good... But I have problems implementing the extractor-objects. They are instanciated by a factory pattern. I did it like this (simplyfied):
abstract class Extractor<E> {
abstract E extract(DTable source, int row);
static <E> Extractor<E> getInstance(int type) {
if(type == 0)
return new IntExtractor();
else
return new StringExtractor();
}
}
class IntExtractor extends Extractor<Integer> {
#Override
Integer extract(DTable source, int row) {
int value = 5;
return new Integer(value);
}
}
class StringExtractor extends Extractor<String> {
#Override
String extract(DTable source, int row) {
String retVal = "hello";
return retVal;
}
}
It compiles, but I get Unsave cast warnings on casting the Integer/String to E. What am I doing wrong? I know, I can simply supress the warnings. But I thought exactly this should be the advantage of Java generics? I cannot make this cast save, because I dont know, which type 'E' really "is"...
Or am I doing something basically wrong?
Note:
I edited my code to a "new" question after I used some information from the first answer...
Your extractors aren't really generic at all. It sounds like you want something like:
public interface Extractor<P> {
P extract(DTable source, int row);
}
but then make the implementations non-generic:
class IntExtractor implements Extractor<Integer> {
Integer extract(DTable source, int row) {
int value = 5;
return new Integer(value);
}
}
Fundamentally your current code is broken, in that I could write:
IntExtractor<String> extractor = new IntExtractor<String>();
String x = extractor.extract(...);
... that would obviously fail, but only at execution time.
I'd say you're doing something basically wrong. If it is an IntExtractor and a StringExtractor, you don't need generics. Just define methods
Integer extract(DTable source, int row)
and
String extract(DTable source, int row)
The Problem isn't your code per-se. The task itself cannot be solved without unsafe casts. Read your own sentence again:
I want to create a HashMap which maps one undefined Object to
another one. Both objects may one of String or Integer.
Java Generics cannot solve this problem for you, because you have to know the type beforehand, otherwise you have to cast.
To be honest, I do not know what you want to achieve with the code you posted, but If you want to use a HashMap, you can do it like this:
private final HashMap<String, Integer> left2Right = new HashMap<String, Integer>();
left2Right.put("one", 1);
int numberOne = left2Right.get("one");
In this case you do not have to cast the values, because the HashMap has String keys and Integer values. If you want to put different types as values, you have to use a supertype of all values. This super type might be Object, the root of the hierarchy. But in those cases you have to cast - because you do not know what kind of object the value is.
private final HashMap<String, Integer> left2Right = new HashMap<String, Object>();
left2Right.put("one", 1);
left2Right.put("two", new Date());
// Because the compiler cannot know that type "one" might be, this isn't allowed and you have to cast the value. It might be anything - in this example Date or Integer.
int numberOne = left2Right.get("one");
I hope that helps.
Both P and E seem not to be used for the input of the extractors so why are you even having them? Just return int and String and be done with it.

How to check type of variable in Java?

How can I check to make sure my variable is an int, array, double, etc...?
Edit: For example, how can I check that a variable is an array? Is there some function to do this?
Java is a statically typed language, so the compiler does most of this checking for you. Once you declare a variable to be a certain type, the compiler will ensure that it is only ever assigned values of that type (or values that are sub-types of that type).
The examples you gave (int, array, double) these are all primitives, and there are no sub-types of them. Thus, if you declare a variable to be an int:
int x;
You can be sure it will only ever hold int values.
If you declared a variable to be a List, however, it is possible that the variable will hold sub-types of List. Examples of these include ArrayList, LinkedList, etc.
If you did have a List variable, and you needed to know if it was an ArrayList, you could do the following:
List y;
...
if (y instanceof ArrayList) {
...its and ArrayList...
}
However, if you find yourself thinking you need to do that, you may want to rethink your approach. In most cases, if you follow object-oriented principles, you will not need to do this. There are, of course, exceptions to every rule, though.
Actually quite easy to roll your own tester, by abusing Java's method overload ability. Though I'm still curious if there is an official method in the sdk.
Example:
class Typetester {
void printType(byte x) {
System.out.println(x + " is an byte");
}
void printType(int x) {
System.out.println(x + " is an int");
}
void printType(float x) {
System.out.println(x + " is an float");
}
void printType(double x) {
System.out.println(x + " is an double");
}
void printType(char x) {
System.out.println(x + " is an char");
}
}
then:
Typetester t = new Typetester();
t.printType( yourVariable );
a.getClass().getName() - will give you the datatype of the actual object referred to by a, but not the datatype that the variable a was originally declared as or subsequently cast to.
boolean b = a instanceof String - will give you whether or not the actual object referred to by a is an instance of a specific class.
Again, the datatype that the variable a was originally declared as or subsequently cast to has no bearing on the result of the instanceof operator.
I took this information from:
How do you know a variable type in java?
This can happen. I'm trying to parse a String into an int and I'd like to know if my Integer.parseInt(s.substring(a, b)) is kicking out an int or garbage before I try to sum it up.
By the way, this is known as Reflection. Here's some more information on the subject: http://docs.oracle.com/javase/tutorial/reflect/
Just use:
.getClass().getSimpleName();
Example:
StringBuilder randSB = new StringBuilder("just a String");
System.out.println(randSB.getClass().getSimpleName());
Output:
StringBuilder
You may work with Integer instead of int, Double instead of double, etc. (such classes exists for all primitive types).
Then you may use the operator instanceof, like if(var instanceof Integer){...}
Well, I think checking the type of variable can be done this way.
public <T extends Object> void checkType(T object) {
if (object instanceof Integer)
System.out.println("Integer ");
else if(object instanceof Double)
System.out.println("Double ");
else if(object instanceof Float)
System.out.println("Float : ");
else if(object instanceof List)
System.out.println("List! ");
else if(object instanceof Set)
System.out.println("Set! ");
}
This way you need not have multiple overloaded methods. I think it is good practice to use collections over arrays due to the added benefits. Having said that, I do not know how to check for an array type. Maybe someone can improve this solution. Hope this helps!
P.S Yes, I know that this doesn't check for primitives as well.
The first part of your question is meaningless. There is no circumstance in which you don't know the type of a primitive variable at compile time.
Re the second part, the only circumstance that you don't already know whether a variable is an array is if it is an Object. In which case object.getClass().isArray() will tell you.
I did it using: if(x.getClass() == MyClass.class){...}
I wasn't happy with any of these answers, and the one that's right has no explanation and negative votes so I searched around, found some stuff and edited it so that it is easy to understand. Have a play with it, not as straight forward as one would hope.
//move your variable into an Object type
Object obj=whatYouAreChecking;
System.out.println(obj);
// moving the class type into a Class variable
Class cls=obj.getClass();
System.out.println(cls);
// convert that Class Variable to a neat String
String answer = cls.getSimpleName();
System.out.println(answer);
Here is a method:
public static void checkClass (Object obj) {
Class cls = obj.getClass();
System.out.println("The type of the object is: " + cls.getSimpleName());
}
Basically , For example :
public class Kerem
{
public static void main(String[] args)
{
short x = 10;
short y = 3;
Object o = y;
System.out.println(o.getClass()); // java.lang.Short
}
}
None of these answers work if the variable is an uninitialized generic type
And from what I can find, it's only possible using an extremely ugly workaround, or by passing in an initialized parameter to your function, making it in-place, see here:
<T> T MyMethod(...){ if(T.class == MyClass.class){...}}
Is NOT valid because you cannot pull the type out of the T parameter directly, since it is erased at runtime time.
<T> void MyMethod(T out, ...){ if(out.getClass() == MyClass.class){...}}
This works because the caller is responsible to instantiating the variable out before calling. This will still throw an exception if out is null when called, but compared to the linked solution, this is by far the easiest way to do this
I know this is a kind of specific application, but since this is the first result on google for finding the type of a variable with java (and given that T is a kind of variable), I feel it should be included
var.getClass().getSimpleName()
Let's take a example
String[] anArrayOfStrings = { "Agra", "Mysore", "Chandigarh", "Bhopal" };
List<String> strList = Arrays.asList(anArrayOfStrings);
anArrayOfStrings.getClass().getSimpleName() //res => String[]
strList.getClass().getSimpleName() // res => ArrayList
You can check it easily using Java.lang.Class.getSimpleName() Method Only if variable has non-primitive type. It doesnt work with primitive types int ,long etc.
reference - Here is the Oracle docs link
I hit this question as I was trying to get something similar working using Generics. Taking some of the answers and adding getClass().isArray() I get the following that seems to work.
public class TypeTester <T extends Number>{
<T extends Object> String tester(T ToTest){
if (ToTest instanceof Integer) return ("Integer");
else if(ToTest instanceof Double) return ("Double");
else if(ToTest instanceof Float) return ("Float");
else if(ToTest instanceof String) return ("String");
else if(ToTest.getClass().isArray()) return ("Array");
else return ("Unsure");
}
}
I call it with this where the myArray part was simply to get an Array into callFunction.tester() to test it.
public class Generics {
public static void main(String[] args) {
int [] myArray = new int [10];
TypeTester<Integer> callFunction = new TypeTester<Integer>();
System.out.println(callFunction.tester(myArray));
}
}
You can swap out the myArray in the final line for say 10.2F to test Float etc
public static void chkType(Object var){
String type = var.getClass().toString();
System.out.println(type.substring(16));
//assertEquals(type,"class java.lang.Boolean");
//assertEquals(type,"class java.lang.Character");
//assertEquals(type,"class java.lang.Integer");
//assertEquals(type,"class java.lang.Double");
}
A simple solution I found was the following rather than wondering about fire command. Also, you can check this article
public class DataTypeCheck
{
public static void main(String[] args)
{
String jobTitle = "Agent";
int employeeId = 7;
double floating= 10.0;
String bond = jobTitle + employeeId;
System.out.println(((Object)floating).getClass().getSimpleName());
System.out.println(((Object)employeeId).getClass().getSimpleName());
System.out.println(((Object)jobTitle).getClass().getSimpleName());
System.out.println(((Object)bond).getClass().getSimpleName());
}
}
Output:
Double
Integer
String
String

Categories