Java: Store int in Integer array - java

Can you store int values into a Integer array?
Given an array:
Integer[] array = new Integer[10];
Are the following two statements equivalent?
Integer x = new Integer(1);
array[0] = x;
int x = 1;
array[0] = x;

They are not 100% equivalent. The following should be equivalent however:
Integer x = Integer.valueOf(1);
array[0] = x;
int x = 1;
array[0] = x;
Note that the int primitive gets autoboxed to the Integer wrapper class. So you're not storing an int primitive in the Integer array, but an Integer object.
You should hardly ever use the Integer constructor (which always creates a new object) but use one of its static factory methods or autoboxing (less code), which allow to cache instances (since they are immutable).

Once the values are inside the array itself, they are both values of type Integer. If you pass a primitive object to an instance of its wrapper class, then that primitive type is autoboxed, meaning its automatically converted to the type of its wrapper class.
Integer x = 4; //autoboxing: "4" is converted to "new Integer(4)"
Likewise, a wrapper class type can is unboxed when it is passed to a primitive type:
int x = new Integer(4); //unboxing: "new Integer(4)" is converted to primitive int 4
For your purposes, both examples your wrote will work.

Related

Difference between creating array of Objects for Classes created by Users and for Classes that already exist in Java

I came to know from this stackoverflow question that the code
test1[] t = new test1[2];
in the following program
class test1{
public int n;
void set(int n1){
n=n1;
}
}
class test{
public static void main(String arg[]){
test1[] t = new test1[2];
for(int i=0;i<2;i++)
t[i] = new test1();
t[0].set(12);
t[1].set(13);
for(int i=0;i<2;i++)
System.out.println(t[i].n);
}
}
is needed to initialize the array of objects of the class test1, and trying to access the objects without the code :
for(int i=0;i<2;i++)
t[i] = new test1();
throws the following error :
Exception in thread "main" java.lang.NullPointerException
at test.main(test1.java:12)
But I also tried to execute the following program:
class test{
public static void main(String args[]){
Integer[] n = new Integer[2];
n[0] = 9;
n[1] = 18;
for(int i=0;i<2;i++){
byte b = n[i].byteValue();
System.out.println(b);
}
}
seems to work without any error although I have not initialized the array of object of the Integer class, using the code :
for(int i=0;i<2;i++)
n[i] = new Integer();
How is it that, the array of objects of the Integer class and that of the class created by me differ in this case.
Is it that the objects for the class that I create requires initialization and the objects for the class Integer does not require initialization. Am I getting it right ? I just wanted to know how the classes that users create and classes that already exist differ.
I have not initialized the array of object of the Integer class, using the code :
Yes, you did initialize the contents of the array n. Just like any reference array, an Integer[] is initialized with all nulls.
However, you did supply values:
n[0] = 9;
n[1] = 18;
You just didn't use new, because Java will autobox the int literals into Integer objects. You are storing the Integer objects corresponding to 9 and 18.
It doesn't matter if the objects are for classes that you create or not. It matters whether you are using a "wrapper" type for Java's primitive values. You can always have Java autobox primitive values into wrapper types, e.g. int to Integer.
The JLS, Section 5.1.7, lists all possible boxing conversions:
From type boolean to type Boolean
From type byte to type Byte
From type short to type Short
From type char to type Character
From type int to type Integer
From type long to type Long
From type float to type Float
From type double to type Double
From the null type to the null type

Casting a primitive vs Creating a object of the primitive

I'm not habitual to casting a primitive data type to an object. Saw some code like:
public static int CompareAges(Person p1, Person p2) {
Integer age1 = p1.getAge();
return age1.compareTo(p2.getAge());
}
The instantiation of age1 seemed extraneous, so I tried to write the code as:
public static int CompareAges(Person p1, Person p2) {
return p1.getAge().compareTo(p2.getAge());
}
But that raised a compiler error because p1.getAge() is a primitive data type int and not an Integer, which is an object.
Intuitively, I did:
public static int CompareAges(Person p1, Person p2) {
return ((Integer) p1.getAge()).compareTo(p2.getAge());
}
and it worked!
The question: What did I miss? Since when did we start casting primitives as value types?
It's what happens internally:
1. Integer age1 = p1.getAge();
Integer != int
Integer = Integer.valueOf(int)
Integer age1 = Integer.valueOf(p1.getAge());
2. p1.getAge().compareTo(p2.getAge());
int.compareTo(int)
^^^
// it's just a primitive type, as a result - the compile error
3. ((Integer) p1.getAge()).compareTo(p2.getAge())
Integer.compareTo(int)
Integer.compareTo(Integer.valueOf(int))
((Integer) p1.getAge()).compareTo(Integer.valueOf(p2.getAge()))
4. (Integer) p1.getAge() ---> Integer.valueOf(p1.getAge())
// why so? look at callOfCode's answer
But, in my opinion, ((Integer) p1.getAge()).compareTo(p2.getAge()) looks ugly.
I would replace it to
p1.getAge() > p2.getAge() ? 1 : (p1.getAge() < p2.getAge() ? -1 : 0)
or to
Integer.compare(p1.getAge(), p2.getAge()) // java 7+
I wouldn't like to do casting in this case.
More about "autoboxing/unboxing" you may find here.
Each primitive has its own boxing type
The Boxing could be implicit (Autoboxing) or explicit like you did it in your code.
p2.getAge() is an Example of AutoBoxing or Implicit Boxing. The method compareTo takes an Object. As it is a primitive, Java converts it automatically to the correspondent Boxing Object (Integer). You did the explicit Boxing with the cast (Integer) p1.getAge()
Difference between new Integer(primitive); and Integer integer = (Integer)primitive; Is only on bytecode level. In the first case, new object of Integer class is created in memory. In the second case, Integer.valueOf(primitive) is called internally. This is the static method that checks if primitive falls into range of -128 to 127 and if it falls, it returns value from integer cache and no new object is being created. If it not falls into that range, new Integer object is instantiated. It is used for efficiency. But such efficiency is unsignificant novadays.
int z = 1;
Integer a = (Integer)z;
Integer b = (Integer)z;
//Prints true, since Integer object is retrieved from cache (range of -128 to 127)
System.out.println(a == b);
int w = 999;
Integer c = (Integer)w;
Integer d = (Integer)w;
//Prints false, since 999 is not in cache, new Integer objects are instantiated and they points to different places in memory
System.out.println(c == d);

What mechanism does Java use so that it does not allow reasignment of an array reference to another with a bigger type?

From a book I've been reading, it said
int[] splats;
int[] dats = new int[4];
char[] letters = new char[5];
splats = dats; //ok
splats = letters; //not ok
What is the mechanism that it does not allow such an assignment?
Edit:
As opposed to this assignment where
int[] weightList = new int[5];
byte b = 4;
char c = 'c';
short s = 7;
weightList[0] = b; //ok
weightList[1] = c; //ok
weightList[2] = s; //ok
this is allowed.
Edit :
I think I understand how widening and narrowing work but in my head
new int[4];
and
new char[4];
are two array objects in the heap with the type of 'array'. Aren't they ?
Perhaps like
new List<int>
and
new List<char>
Sure their individual element types are different but the List objects themselves
are of the same List type.
I read that arrays of objects are allowed to perform that operation as long as
the assigning side has a narrower type(subclass).
So maybe I could think of this like
Because the primitive type char does not inherit the primitive type
int, you cannot reassign an array of chars into an array of ints ?
well of course, one primitive type "extending" another doesn't sound right but just
to make it easier to understand.
The 'mechanism' is type safety.
A reference to char[] is not the same type as a reference to int[]
There is no inheritance-relationship between them
There is no specified widening conversion rule
So the assignment is illegal.
The compiler checks the types. An array of primitives can only be assigned to another array of primitives with the same type.
weightList[0] = b; //ok because its byte
weightList[1] = c; //ok because it converts to ASCII
weightList[2] = s; //ok Directly store , because its short
Yes, These can easily mapped into the int array. Because individually the values are inserted into the index (0,1,2) those values must be less than capacity of int data type.The size and length matter ,when type casting. That may be upper bound or lower bound.Read here.
splats = dats; //ok
There splats is holding a referecne to an array of int type, regardless of the size/length. It can hold the reference to other array but only of int type.
splats = letters;
In the above line, types are different, so it can't be assigned.
For your edit:
weightList[0] = b; //ok
since weightList is of type int and it can accomodate char, byte and short data type because int is 32 bit, where as byte is 8 bits and short and char is 16 bit.
You should see: 5.1.2. Widening Primitive Conversion
19 specific conversions on primitive types are called the widening
primitive conversions:
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
A widening primitive conversion does not lose information about the
overall magnitude of a numeric value.
You asked about Java mechanism. In this short example java uses Widening Primitive Conversion and Narrowing Primitive Conversion. To understand more clearly? you can read this article
Java allows assignment of an array reference only when the types of the arrays themselves are identical, not when the element types are merely assignment compatible. This is referred to as having "invariant" arrays.
This has nothing to do with the length of the array, but rather the type.
And this is not affected by whether the elements can be individually assigned particular values by having the values silently widened.
For arrays apply the same rules as for any other type of variable. If the array is of the same type or derived from it you can assign it, otherwise not.
For Example:
JComponent[] a = null;
JTextField[] b = null;
a = b; <- OK, because JTextfield is derived from JComponent.
b = a; <- error because JComponent is NOT derived from JTextField
It doesn't matter if this is an array or not, because only the type matters:
JComponent a = null;
JTextField b = null;
a = b; <- OK, because JTextfield is derived from JComponent.
b = a; <- error because JComponent is NOT derived from JTextField
In your case, char and int are unrelated to each other, so they can not be assigned.

What is the main difference between primitive type and wrapper class?

What is the difference between these two lines?
int pInt = 500;
and
Integer wInt = new Integer(pInt);
Or
Integer wInt = new Integer(500);
None.
That's the exact same thing. In the first case you just have a supplementary variable.
Note that with autoboxing you rarely need to have both an int and an Integer variables. So for most cases this would be enough :
int pInt = 500;
The main case where the Integer would be useful is to distinguish the case where the variable is not known (ie null) :
Integer i = null; // possible
int i = null; // not possible because only Object variables can be null
But don't keep two variables, one is enough.
In Java, an instance of a primitve class holds the actual value of the instance, but instance of a wrapper class holds a reference to the object. i.e. The address of the place where the object would be found.
When you write a program with this line:
Integer integer = 500;
The compiler changes it to this:
Integer integer = new Integer(500);
This process is called autoboxing. That is automatically putting a primitive-instance in a "box" of Integer. Hence, output of the following program:
public class PrimitiveToObject {
public static void main(String[] args) {
printClassName(1);
printClassName(1L);
printClassName((char)1);
}
public static void printClassName(Object object){
System.out.println(object.getClass());
}
}
is this:
class java.lang.Integer
class java.lang.Long
class java.lang.Character
Also this:
int i = integer;
changes into this:
int i = integer.intValue();
This is called unboxing.
As you can see above, the dot operator(.) is used on the variable named integer but not on i. That is: a wrapper's object can be dereferenced, but not a primitive instance.
Boxing and unboxing may slow down the program a little bit. Hence, to a newbie, wrappers may look like added burden, but they are not so. Wrappers are used at places where the object needs to be a reference type. eg: Map<Integer,String>map=new HashMap<Integer,String>(); is a valid statement, but Map<int,String>map=new HashMap<int,String>(); is not a valid statement.
Another typical case where wrapper is very useful: In MySQL, NULL is a valid entry for a column of INT type. But in Java, int cannot have a null value, Integer can. This is because in SQL NULL symbolises Not Available. So if you are using JDBC to insert integer values in a MySQL table, a null in your java program will help in inserting NULL in the MySQL table.
A wrapper class can also be useful in a case similar or anologous to this:
Boolean decision; // Using wrapper for boolean.
if("YES".equalsIgnoreCase(consent))
decision = Boolean.TRUE; // In favour
else if("NO".equalsIgnoreCase(consent))
decision = Boolean.FALSE; // Not in favour
else if("CAN'T SAY".equalsIgnoreCase(consent))
decision = null; // Undecided
For starters
int pInt = 500; , here pInt is not an object whereas in
Integer wInt = new Integer(500);
wInt is an reference
This is also a reason why java is not pure Object Oriented Language. Because everything is not object with java.
Wrapper class will have a box in that box it will cover the primitive data types there are 8 primitive data types namely byte,int ,long ,double, float, short ,Boolean ,char these all covered in wrapper class .
to use primitive data types we use like int a;
but to use wrapper class we need to use like Integer a = new Integer(i);
The types of data are the same, but there are situations that manipulation of objects is more convenient than primitive types, like data structures, where you need more control of your data types.
For example, objects can be null and primitive types can't.
You also can't call methods in a primitive type (.compareTo(), .equals(), ...), but in wrapper classes you can.
The information below describe the types in primitive and wrapper class:
Primitive Types | Wrapper Class (Superclass = Object)
boolean - Boolean
char - Character
Primitive Types | Wrapper Class (Superclass = Number)
byte - Byte
short - Short
int - Integer
long - Long
float - Float
double - Double
To understand how the wapper classes works, consider the example below:
public final class IntWrapper {
private final int intVal;
IntWrapper(int intVal) {
this.intVal = intVal;
}
public int getInt() {
return intVal;
}
}
Now we can make an object out of our new IntWrapper class and 'box' the primitive int value 41:
int i = 41;
IntWrapper iw = new IntWrapper( i ); // box the primitive int type value into the object
i = iw.getInt(); // unbox the value from the wrapper object
My example IntWrapper class is immutable, immutable means that once its state has been initialized its state cannot be changed.
When the final keyword is applied to a class, the final class cannot be extended. In other words, a final class can never be the superclass of a subclass. A final class can be the subclass of superclass, not problem there. When a class is marked final, all of its methods are implicitly final as well.
It is important to note that when final is applied to a reference variable it does not prevent the members of the object instance from changing values.
This example is to better understanding how the wrapper classes works inside.
Next, to create Integer, Double and other wrapper classes, you can write:
Integer i = new Integer(4);
Double d = new Double(9.62);
Boolean b = new Boolean("true");
Character c = new Character('M');
To get the encapsulated number into wrapper objects, you can write:
long l = i.longValue();
double e = i.doubleValue();
float f = d.floatValue();
short s = d.shortValue();
Each wrapper class include special methods to convert between primitive type to wrapper objects, that represent not number values:
boolean bo = b.booleanValue();
char ch = c.charValue();
Up to Java 5 version, the creation of objects from wrapper classes had to be in the syntaxes like above, but to simplify these operations, mainly related to insertion of values in the data structures offered in Java collections (that only accept objects), now exists the autoboxing or boxing and autounboxing or unboxing options.
The autoboxing or boxing allows you to insert a primitive value to reference of equivalent wrapper types or Object type:
// Same result of Double d = new Double(-2.75);
Double objD = -2.75;
// Same result of Object objI = new Integer(13);
Object objI = 13;
The autounboxing or unboxing allows you to insert a wrapper object into a variable of primitive type, converting automatically between equivalent types:
// Same result of double vd = objD.doubleValue();
double vd = objD;
// Same result of int vi = objI.intValue();
int vi = objI;
The most important practical difference I've seen is Integer is way more slower to initialize and do calculations with, than int. I would avoid Integer unless necessary.
int x = 20_000_000;// 20 millions
for (int i = 0; i < x; i++) {
ix += 23;
}
it takes 138 ms(average over 50 trials) to complete the loop when ix is an Integer but only takes 10 ms when ix is an int

declaring/initializing primitives equal to creating new objects

is declaring/initializing primitives the same as creating new objects? from what i know when we create primitives, we also creating wrapper classes for them. im implementing on java btw.
No, assigning primitive values does not create any objects.
What you might be referring to is the fact that primitive values can be auto-boxed into the corresponding wrappers, when they are used in a context where a reference type (a.k.a "an object") is required:
int i = 13; // this line does not create an object
Integer i2 = i; // at this line 13 is auto-boxed into an Integer object
char c = 'x'; // again: no object created:
List<Character> l = new ArrayList<Character>();
l.add(c); // c is auto-boxed into a Character object
Also, I'll try to describe the difference between declare and initialize:
int i; // an int-variable is declared
int j = 0; // an int-variable is declared and initialized
i = 1; // an int-variable is assigned a value, this is *not* initialization
A variable is "declared" when it is created for the first time (i.e. you specify the type and name of the variable). It is initialized when it's assigned a value during declaration.
No, declaring and initializing a primitive variable does not create an object. Let's take a class with two integer values - one using the wrapper type and one not.
public class Foo
{
private int primitive = 10;
private Integer wrapper = new Integer(10);
}
The value of the primitive variable is just the number 10. The value of the wrapper variable is a reference to an Integer object which in turn contains the number 10. So an instance of Foo would keep state for the number in primitive and the reference in wrapper.
There are wrapper classes for all primitive types in Java, but you don't use them automatically.
Creating a primitive DOES NOT also create a wrapper class for them.
As for your original question: Declaring/initializing a primitive will create it on the stack, whereas declaring an object will allocate a variable to hold a reference to an object. Initializing the object will allocate it on the heap.
Answer: No.
Check this out: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
No. Primitives are not objects in java.

Categories