Java: many ways of casting a (long) Object to double - java

I have an Object obj that I know is actually a long.
In some Math code I need it as double.
Is it safe to directly cast it to double?
double x = (double)obj;
Or should I rather cast it first to long and then to double.
double x = (double)(long)obj;
I also found another (less readable) alternative:
double x = new Long((long)obj).doubleValue();
What are the dangers/implications of doing either?
Solution Summary:
obj is a Number and not a long.
Java 6 requires explicit casting, e.g.: double x = ((Number)obj).doubleValue()
Java 7 has working cast magic: double x = (long)obj
For more details on the Java6/7 issue also read discussion of TJ's answer.
Edit: I did some quick tests. Both ways of casting (explicit/magic) have the same performance.

As every primitive number in Java gets cast to its boxing type when an object is needed (in our case Long) and every boxed number is an instance of Number the safest way for doing so is:
final Object object = 0xdeadbeefL;
final double d = ((Number)object).doubleValue();
The danger here is, as always, that the Object we want to cast is not of type Number in which case you will get a ClassCastException. You may check the type of the object like
if(object instanceof Number) ...
if you like to prevent class cast exceptions and instead supply a default value like 0.0. Also silently failing methods are not always a good idea.

I have an Object obj that I know is actually a long.
No, you don't. long is a primitive data type, and primitive types in Java are not objects. Note that there's a difference between the primitive type long and java.lang.Long, which is a wrapper class.
You cannot cast a Long (object) to a long (primitive). To get the long value out of a Long, call longValue() on it:
Long obj = ...;
long value = obj.longValue();
Is it safe to directly cast it to double?
If it's actually a primitive long, then yes, you can cast that to a double. If it's a Long object, you don't need to cast, you can just call doubleValue() on it:
double x = obj.doubleValue();

Simple casting should work perfectly fine. This will be faster than going via the wrapper classes, getting string representation and then parsing to double, create new instance again using the long value - and more importantly, it's more readable.
double d = (double)15234451L;

You can cast it to a Long (since the Object is not a long but a Long), and then cast the Long to a double:
double d = (double)(Long)obj;
For instance, this has the expected output of 2.6666666666666665:
public class CastDouble {
public static final void main(String[] args) {
Object o = 15L;
System.out.println(40 / (double)(Long)o);
}
}

You only need one cast, from Object to Long or long (which implicitly casts to Long then applies unboxing):
Object o = 5L;
double d = (long) o; //Apparently only works on Java 7+
//or
double d = (Long) o;

Related

Do java type casting matter? Does it necessarily need to know at the beginner stage?

Do java type casting matter? Does it necessarily need to know at the beginner stage?
**double myDouble = 9.78;
int myInt = (int) myDouble;**
This make me confuse at the first stage.
Do java type casting matter? Does it necessarily need to know at the
beginner stage?
Yes, it does matter. Without the cast operator, this would be a compile-time error. Check this chapter of JLS to learn more about it.
In simple terms, consider variables as containers e.g. an int type of variable has a capacity of 4 bytes while a double type of value needs 8 bytes. Therefore, if you try to assign a double type of value to an int type of variable, it won't fit. The cast operator makes it possible by pruning the double value to fit into the int variable. On the other hand, if you try to assign an int type of value to a double type of variable, the value can be accommodated without requiring any casting.
public class Main {
public static void main(String[] args) {
double myDouble = 9.78;
int myInt = (int) myDouble;// Casting is required
int x = 100;
myDouble = 100;// Casting is not required
}
}

ArrayList storing other than specified datatypes

I have an ArrayList with type Long,but i am trying to insert int value in it.I am expecting int should also be stored in ArrayList as int is smaller in size than long.
int i=1;
ArrayList<Long> obj=new ArrayList<Long>();
obj.add(i);//It is showing error that Storing int is not possible
Whereas the below one is possible
List item
long l=0;
int i=5;
l=i;
Please suggest the reason why ArrayList can't store lower value types.
This:
ArrayList<Long> obj=new ArrayList<Long>();
is declaring that the list will store objects of type Long. It's storing references, and you can't put an Integer in, since an Integer is-not a Long (from the point of view of an object hierachy)
Don't think of the issue in term of numbers. Instead, try this. You have a list of Cats. You can't store a Dog in there. But you could if the list was declared as a list of Animals.
You could declare the list to contain a Number (Longs and Integers are both Numbers), but the fundamental issue is why are you mixing integers and longs in this collection ?
You are doing this:
Long l = 0L;
int i = 5;
l=i;//Type mismatch: cannot convert from int to Long
not this:
long l = 0;
int i = 5;
l = i;
It is not an ArrayList matter, look at this for details.
You just need to cast it to a long to make the above code work:
obj.add((long)i);
Because you specified that the ArrayList contains "Long", it forces all objects that go into it to be Long. And since ArrayList can be used to store any type of data, not just numbers, it doesn't have built-in mechanisms to convert ints to longs for example. Different rules apply.
Java primitives, like int and long, allow automatic conversion to comply with the way that C and C++ work, since Java was based on these languages originally. But it doesn't lead to the cleanest/safest code, and so some other more modern languages have removed even this type of fuziness.
The long variable l also can't store lower value types. The assignment of i to l will implicitly do a Widening Primitive Conversion, and the value is stored as a long.
When you try to insert an int value into a List<Long>, you're implicitly trying to do two conversions:
Widening Primitive Conversion (int to long)
Boxing Conversion (long to Long)
That double conversion will not be applied implicitly, so you have to tell the compiler to do it, by forcing the widening primitive conversion using a cast:
obj.add((long)i);
You have declared obj to be a list of Long and thus it restricts you to use add
/**
* Appends the specified element to the end of this list.
*
* #param e element to be appended to this list
* #return <tt>true</tt> (as specified by {#link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
Note - where E is from the class definition ArrayList<E> extends AbstractList<E>
to primarily add only the type that your list should be consisting of. Hence changing the code as follows should work :
int i=1;
ArrayList<Long> obj=new ArrayList<Long>();
obj.add(Long.valueOf(i));
Also in your latter part the cast is taken care by the = operator as you assign it in following way :
l=i;
An ArrayList<Long> can only store instances of Long.
You can "apparently" store longs in it, because the long is autoboxed to a Long:
list.add(someLong)
gets compiled to
list.add(Long.valueOf(someLong))
Boxing conversion only applies from primitive to corresponding wrapper type: long to Long, int to Integer etc. It doesn't box an int to a Long, however. The compiler isn't that smart/lenient.
And Java doesn't widen an Integer to a Long, because widening isn't defined for those types: it's only defined for primitive numeric types.
You've just got to make the parameter a long, then it can autobox for you:
obj.add((long) i);
or, without autoboxing:
obj.add(Long.valueOf(i));
Note, in the latter case, int is an acceptable parameter for a method taking a long parameter because of widening conversion. Widening + autoboxing just isn't supported.

What is .intValue() in Java?

What is the difference between them?
l is an arraylist of Integer type.
version 1:
int[] a = new int[l.size()];
for (int i = 0; i < l.size(); i++) {
a[i] = l.get(i);
}
return a;
version 2:
int[] a = new int[l.size()];
for (int i = 0; i < l.size(); i++) {
a[i] = l.get(i).intValue();
}
return a;
l.get(i); will return Integer and then calling intValue(); on it will return the integer as type int.
Converting an int to Integer is called boxing.
Converting an Integer to int is called unboxing
And so on for conversion between other primitive types and their corresponding Wrapper classes.
Since java 5, it will automatically do the required conversions for you(autoboxing), so there is no difference in your examples if you are working with Java 5 or later. The only thing you have to look after is if an Integer is null, and you directly assign it to int then it will throw NullPointerException.
Prior to java 5, the programmer himself had to do boxing/unboxing.
As you noticed, intValue is not of much use when you already know you have an Integer. However, this method is not declared in Integer, but in the general Number class. In a situation where all you know is that you have some Number, you'll realize the utility of that method.
The Object returned by l.get(i) is an instance of the Integer class.
intValue() is a instance method of the Integer class that returns a primitive int.
See Java reference doc...
http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html#intValue()
Java support two types of structures first are primitives, second are Objects.
Method that you are asking, is used to retrieve value from Object to primitive.
All java types that represent number extend class Number. This methods are in someway deprecated if you use same primitive and object type since [autoboxing] was implemented in Java 1.5.
int - primitive
Integer - object
Before Java 1.5 we was force to write
int i = integer.intValue();
since Java 1.5 we can write
int i = integer;
Those methods are also used when we need to change our type from Integer to long
long l = integer.longValue();
Consider this example:
Integer i = new Integer(10);
Integer j = new Integer(10);
if (!(i == j)) {
System.out.println("Surprise, doesn't match!");
}
if (i.intValue() == j.intValue()) {
System.out.println("Cool, matches now!");
}
which prints
Surprise, doesn't match!
Cool, matches now!
That proves that intValue() is of great relevance. More so because Java does not allow to store primitive types directly into the containers, and very often we need to compare the values stored in them. For example:
oneStack.peek() == anotherStack.peek()
doesn't work the way we usually expects it to work, while the below statement does the job, much like a workaround:
oneStack.peek().intValue() == anotherStack.peek().intValue()
get(i) will return Integer object and will get its value when you call intValue().In first case, automatically auto-unboxing happens.
They are exactly the same. As other posters have mentioned, you can put either the Integer object or the int primitive into the array. In the first case, the compiler will automatically convert the Integer object into a primitive. This is called auto-boxing.
It's just a convenience method for getting primitive value from object of Number: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Number.html
Consider the code:
Integer integerValue = Integer.valueOf(123);
float floatValue = integerValue.floatValue();
The last line is a convenient method to do:
float floatValue = (float)(int)integerValue;
Since any numeric type in Java can be explicitly cast to any other primitive numeric type, Number class implements all these conversions. As usual, some of them don't make much sense:
Integer integerValue = Integer.valueOf(123);
int intValue = integerValue.intValue();
int intValue2 = (int)integerValue;
int intValue3 = integerValue;

What is the difference between Double.parseDouble(String) and Double.valueOf(String)?

I want to convert String to a Double data type. I do not know if I should use parseDouble or valueOf.
What is the difference between these two methods?
parseDouble returns a primitive double containing the value of the string:
Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.
valueOf returns a Double instance, if already cached, you'll get the same cached instance.
Returns a Double instance representing the specified double value. If
a new Double instance is not required, this method should generally be
used in preference to the constructor Double(double), as this method
is likely to yield significantly better space and time performance by
caching frequently requested values.
To avoid the overhead of creating a new Double object instance, you should normally use valueOf
Double.parseDouble(String) will return a primitive double type.
Double.valueOf(String) will return a wrapper object of type Double.
So, for e.g.:
double d = Double.parseDouble("1");
Double d = Double.valueOf("1");
Moreover, valueOf(...) is an overloaded method. It has two variants:
Double valueOf(String s)
Double valueOf(double d)
Whereas parseDouble is a single method with the following signature:
double parseDouble(String s)
parseDouble() method is used to initialise a STRING (which should contains some numerical value)....the value it returns is of primitive data type, like int, float, etc.
But valueOf() creates an object of Wrapper class. You have to unwrap it in order to get the double value. It can be compared with a chocolate. The manufacturer wraps the chocolate with some foil or paper to prevent from pollution. The user takes the chocolate, removes and throws the wrapper and eats it.
Observe the following conversion.
int k = 100;
Integer it1 = new Integer(k);
The int data type k is converted into an object, it1 using Integer class. The it1 object can be used in Java programming wherever k is required an object.
The following code can be used to unwrap (getting back int from Integer object) the object it1.
int m = it1.intValue();
System.out.println(m*m); // prints 10000
//intValue() is a method of Integer class that returns an int data type.
They both convert a String to a double value but wherease the parseDouble() method returns the primitive double value, the valueOf() method further converts the primitive double to a Double wrapper class object which contains the primitive double value.
The conversion from String to primitive double may throw NFE(NumberFormatException) if the value in String is not convertible into a primitive double.
Documentation for parseDouble() says "Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.", so they should be identical.
If you want to convert string to double data type then most choose parseDouble() method.
See the example code:
String str = "123.67";
double d = parseDouble(str);
You will get the value in double. See the StringToDouble tutorial at tutorialData.

Initializing a Double object with a primitive double value

What is happening when a java.lang.Double object is initialized without using a call to the constructor but instead using a primitive? It appears to work but I'm not quite sure why. Is there some kind of implicit conversion going on with the compiler? This is using Java 5.
public class Foo {
public static void main(String[] args) {
Double d = 5.1;
System.out.println(d.toString());
}
}
This is called Autoboxing which is a feature that was added in Java 5. It will automatically convert between primitive types and the wrapper types such as double (the primitive) and java.lang.Double (the object wrapper). The java compiler automatically transforms the line:
Double d = 5.1;
into:
Double d = Double.valueOf(5.1);
It is called AutoBoxing
Autoboxing and Auto-Unboxing of
Primitive Types Converting between
primitive types, like int, boolean,
and their equivalent Object-based
counterparts like Integer and Boolean,
can require unnecessary amounts of
extra coding, especially if the
conversion is only needed for a method
call to the Collections API, for
example.
The autoboxing and auto-unboxing of
Java primitives produces code that is
more concise and easier to follow. In
the next example an int is being
stored and then retrieved from an
ArrayList. The 5.0 version leaves the
conversion required to transition to
an Integer and back to the compiler.
Before
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = (list.get(0)).intValue();
After
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, 42);
int total = list.get(0);
It's called autoboxing.

Categories

Resources