What should you do to insert a primitive value in a data structure that stores only Objects??Look to this code snippet, I want to add the integer value 5 to an ArrayList but I can't do that directly. You should convert the primitive value (here is int) to the corresponding type-wrapper class (here is Integer), and hence you can add 5 to the array. To retrieve this element, you should cast the return of the ArrayList's get method to Integer then assign it to Integer variable
ArrayList arrayList=new ArrayList();
Integer i=new Integer(5);
arrayList.add(i);
Integer y=(Integer) arrayList.get(0);
int z=y.intValue(); //get the int value of Integer
System.out.print(z);
J2SE 1.5 supports autoboxing and auto-unboxing conversions; they made writing such a snip of code easier.
Autoboxing conversion: automatically converts a value of a primitive type to an object of the corresponding type-wrapper class.
Auto-unboxing conversion: converts an object of a type-wrapper class to a value of the corresponding primitive type.
So, there is no need to create a type wrapper-class of the primitive type variable just you can assign directly an object of a type-wrapper class to a variable of the corresponding primitive type or a value of primitive type to a variable of the corresponding type-wrapper class.
You can write the last code snippet as following, the boxing and unboxing conversions have done automatically.
ArrayList arrayList = new ArrayList();
arrayList.add(1);
int x=(Integer) arrayList.get(0);
System.out.print(x);
Hint: (Integer) arrayList.get(0) the explicit cast here to Integer is a must because get method returns an Object and you can't assign a reference to superclass object(here Object) to a subclass variable(here Integer) without the explicit casting. But of course, you can assign a reference to a subclass to superclass variable without casting, implicit cast has already done by the compiler.
The Sixth Feature: Generics
Generics is a new features supported by J2SE 1.5 that helps you in developing a class that work on any type, that specific type is specified only after declaring an instance of the class.
For example I've a problem; I want to extract unique elements from an array, these elements can be integers, double, character or any object. Generics will help in solving this problem easily without developing a class for each type. All you need is only one class that will operate on all types.
These two classes solve this problem; the first one is a generic class that is implemented to operate on any object.
import java.util.Arrays;
import java.util.ArrayList;
public class Extract
{
private ArrayList array=new ArrayList();
/** Returns an array list of a specific type after extracting the passed array */
public ArrayList doExtract(E[] data)
{
Arrays.sort(data);
array.add(data[0]);
for(int index=0 ; index
{
int current=index;
if(!data[++index].equals(data[current]))
array.add(data[index]);
}
return array;
}
/** prints the array before extracting it */
public String print(E[] data)
{
StringBuffer string=new StringBuffer();
int size=data.length;
for(int index=0; index index++)
string.append(data[index]+",");
string.append(data[size-1]);
return string.toString();
}
}
Now in the second class it's the time for declaring an instance of the class and specifying the type the program will operate on. Here three types(Integer,Character and String).
import java.util.ArrayList;
public class TestExtract
{
private static Integer[] i={1,3,5,2,1,2,1,3,4};
private static Character[] c={'a','s','d','a','a','d'};
private static String[] s={"Mohamed","Ali","Ahmed","Ahmed"};
private static ArrayList intArray=new ArrayList();
private static Extract intElements=new Extract();
private static Extract charElements=new Extract();
private static Extract stringElements=new Extract();
public static void main(String[] args)
{
System.out.printf("The integer array is [%s]\n",intElements.print(i));
intArray= intElements.doExtract(i);
System.out.printf("The integer array after extraction is %s\n\n",intArray);
System.out.printf("The character array is [%s]\n",charElements.print(c));
System.out.printf("The character array after extraction is %s\n\n",charElements.doExtract(c));
System.out.printf("The string array is [%s]\n",stringElements.print(s));
System.out.printf("The string array after extraction is %s\n\n",stringElements.doExtract(s));
}
}
Finally, that is a method that uses var-args, enhanced for statement and generics. It takes its parameter as type parameter using generics and use var-args to take any number of inputs and find the maximum number between them.
public class Maximum
{
public static <T extends Comparable <T> > T max (T... inputs){
T max =inputs[0];
for(T member:inputs)
if(member.compareTo(max)>0)
max=member;
return max;
}
public static void main(String[] args) {
System.out.printf("%d \n", max(1,2,3)) ;
System.out.printf("%.1f \n", max(2.8,7.5)) ;
System.out.printf("%s \n",max('a','b','c','d','f','g','j','y','u')) ;
}
}
The type parameter section specifies that T extends Comparable< T > so that only objects of classes that implement interface Comparable< T > can be used with this method.The restriction of using Comparable< T > objects is important because not all objects can be compared.
the arguments to a generic method must be of a reference type. So the compiler autoboxes the three int values as Integer objects and specifies that the three Integer objects will be passed to max.and that's allowed because class Integer, Double and Character (package java.lang) implements the Comparable< Double >,Comparable< Integer > and Comparable< Character > interface respectively.
The last feature is used in the overriding
when you override a method of a superclass in a subclass, it must have the same change return type and the argument
but in java 5 you can change the return type as long as the new return type is a subclass of the previous return type.
For example:
class A
{
A doSomething(int x)
{
return new A();
}
}
class B extends A
{
B doSomething(int x) //legal override in java 1.5
{
return new B();
}
}
So this line B doSomething(int x) will not make any troubles because B is a subclass for the superclass A, so you can override the A's doSomething method in class B and use B as a return type instead of A.
Amira