You are on page 1of 13

1ava Generics

The Generics permits us to develop classes and objects that can work on any deIined types.
In general words, Generics allows us to create a single method Ior sorting that can be used to
sort Integer array, a String array or any type that supports ordering. Similarly, a generic class
allows us to use this class Ior any deIined types.
Generics permits us to catch the incompatible types during compilation. The main reason oI
using Generics code is to assures type saIety. It means that types which are required Ior
Application and the types which is sent by the client, must match. II there is diIIerence or match
is incompatible then it will leads to error. To ensure this match or compatibility we use Generics.
In Generics, classes and methods are deIined with parametric type. You can replace a suitable
java type during compilation with the help oI these parametric type. This saves us Irom un-
necessary type casting and also prevent us Irom using wrong or incompatible data types.
efore Generics
Map directory = new HashMap();
directory.put(new Long(9568575757L), "Sameer");
directory.put(new Long(9587654757L), "Joy");

Set dirValues = directory.entrySet();
Iterator dirIterator = dirValues.iterator();

while (dirIterator.hasNext())
,
Map.Entry anEntry = (Map.Entry)dirIterator.next();
Long number = (Long)anEntry.getKey();
String name = (String)anEntry.getValue();
System.out.println(number + ":" + name);
,
fter Generics
Map<Long, String directory = new HashMap<Long, String();
directory.put(new Long(9568575757L), "Sameer");
directory.put(new Long(9587654757L), "Joy");

Set<Map.Entry<Long, String dirValues = directory.entrySet();
Iterator<Map.Entry<Long, String dirIterator = dirValues.iterator();

while (dirIterator.hasNext())
,
Map.Entry<Long, String anEntry = dirIterator.next();
Long number = anEntry.getKey();
String name = anEntry.getValue();
System.out.println(number + ":" + name);
,
Java Generics
eIore the advent oI Java 5 we had only Arrays, Properties, and HashMap. ut with Java 5 and
generics Ieatures, building a ValuePair has become simpler. In Iact generics is the concept that
generalizes the use oI variables. The situation with generics is quite simple but building classes
with them is a tuII task. The syntax is complex and the abstraction level is high.

Java generics takes several steps to use them:
Iirst deIine an interIace:
public interIace
CoupleP, Q~
public P getIndex();
public Q
getValue();
}
The code is simple but slightly diIIerent iI the developer is unknown with the Java 5 syntax. The
Iirst thing that is new to the developer is the use oI P, Q~. These are nothing but the generic
types that has to be deIined later. These types are not known in advance and is available at
compile time (at the time oI declaration oI these variables). To clearly understand lets see the
implementation:
public class ValuePairA, ~
implements CoupleA, ~

private A a;
private b;

public ValuePair(A a, b)
this.a a;
this.b b;
}

public A getIndex()
return a;
}

public getValue()
return b;
}

}
Now there should not have much more conIusion about generics. Since the class includes the
generiIied interIace thereIore it also includes the generic types. We can use these generic types oI
any two diIIerent types (such as int and Iloat, long and int or any combination oI two diIIerent
types.) Things are going to be more interested while subclassing a base class.
public class NameValuePairT~ extends
ValuePairString, T~

public NameValuePair(String a, T b)
super(a, b);
}

public String getName()
return getIndex();
}

}
From the above code it is clearly understood that only one parameter is required because other
parameter is already deIined as the String.
You have seen the advantages oI using generic classes. We can use them as a Iamily oI variables
according their signature.
:toboxing and Unboxing
The :toboxing and Unboxing was released with the Java 5.
:toboxing
During assignment, the automatic transIormation oI primitive type(int, Iloat, double etc.) into
their object equivalents or wrapper type(Integer, Float, Double,etc) is known as :toboxing.
During assignment or calling oI constructor, the automatic transIormation oI wrapper types into
their primitive equivalent is known as Unboxing.
onversion of int into Integer
int inative = 0;

inative = new Integer(5); // auto-unboxing

Integer intJbject = 5; // autoboxing
$toring int a into vector vt
int a = 10;

Vector <integer vt = new Vector <integer ();

vt.add(a);

int n = vt.elementAt(0); </integer</integer
:toboxing also works with comparison
int a = 10;

Integer b = 10;

System.out.println(a==b);
Output oI the above code will be :
CuLpuL
Lrue

oxing/Unboxing of haracter val:e :


public class MainClass ,
public static void main(String args,) ,
Boolean booleanJbject = true;

if (booleanJbject),
System.out.println("b is true");
,

Character ch = 'x'; // box a char
char ch2 = ch; // unbox a char

System.out.println("ch2 is " + ch2);
,
,
a`\a`
b ls Lrue
ch2 ls x
:toboxing/:nboxing of primitive types
When adding a primitive data type,conversion between primitive types and wrapper classes is
necessary to a collection. For example, an int is stored and then Ietched Irom an ArrayList:
list.add(0, new Integer(59));
int n = ((Integer)(list.get(0))).intValue();

This new Ieature eliminates this manual conversion. The above lines can be written as:
list.add(0, 59);
int total = list.get(0);

However, the wrapper class, Integer Ior example, must be used as a generic type:

List<Integer list = new ArrayList<Integer();


The autoboxing and auto-unboxing oI Java primitives produces code that is more concise and
easier to Iollow.
int i = 10;

Integer iRef = new Integer(i); // Explicit Boxing
int j = iRef.intValue(); // Explicit Unboxing

iRef = i; // Automatic Boxing
j = iRef; // Automatic Unboxing

In oxing ,it converts primitive values to wrapper types: iI p is a value oI a primtiveType,
boxing converts p into corresponding WrapperType, such that ref.primitiveTypeValue() ==
p.
n Unboxing , it converts objects oI wrapper types to primitive types: iI ref is a reIerence oI a
WrapperType, unboxing converts the reIerence ref into ref.primitiveTypeValue().
Assignment conversions on boolean and numeric types:
boolean boolVal = true;
byte b = 2;
short s = 2;
char c ='2';
int i = 2;

// Boxing
Boolean boolRef = boolVal;
Byte bRef = 88;
Short sRef = 2;
Character cRef = '2';
Integer iRef = 2;
// Integer iRef1 = s; // WRJNG ! short not assignable to Integer

// Unboxing
boolean boolVal1 = boolRef;
byte b1 = bRef;
short s1 = sRef;
char c1 = cRef;
int i1 = iRef;

Method invocation conversions on actual parameters:
...
flipFlop("(String, Integer, int)", new Integer(4), 2004);
...
private static void flipFlop(String str, int i, Integer iRef) ,
out.println(str + " == (String, int, Integer)");
,

The output:
(String, Integer, int) == (String, int, Integer)

Casting conversions:
Integer iRef = (Integer) 2; // Boxing followed by identity cast
int i = (int) iRef; // Unboxing followed by identity cast
// Long lRef = 2; // WRJNG ! Type mismatch: cannot convert from
int to Long
// Long lRef = (Long) 2; // WRJNG ! int not convertible to Long
Long lRef_1 = (long) 2; // JK ! explicit cast to long
Long lRef_2 = 2L; // JK ! long literal

Numeric promotion: unary and binary:
Integer iRef = 2;
long l1 = 2000L + iRef; // binary numeric promotion
int i = -iRef; // unary numeric promotion

In the if statement, condition can be Boolean:

Boolean expr = true;
if (expr) ,
out.println(expr);
, else ,
out.println(!expr); // Logical complement operator
,

In the switch statement, the switch expression can be Character, Byte, Short or Integer:
// Constants
final short JNE = 1;
final short ZERJ = 0;
final short NEG_JNE = -1;

// int expr = 1; // (1) short is assignable to int. switch works.
// Integer expr = 1; // (2) short is not assignable to Integer. switch
compile error.
Short expr = 1; // (3) JK. Cast is not required.
switch (expr) , // (4) expr unboxed before case comparison.
case JNE:
out.println("JNE"); break;
case ZERJ:
out.println("ZERJ"); break;
case NEG_JNE:
out.println("NEG_JNE"); break;
default:
assert false;
,

The output:
JNE

In the while, do-while and Ior statements, the condition can be Boolean:
Boolean expr = true;
while (expr) ,
expr = !expr;
,

Character, version = , '5', '.', '0' ,; // Assignment: boxing
for (Integer iRef = 0; // Assignment: boxing
iRef < version.length; // Comparison: unboxing
++iRef) , // ++: unboxing and boxing
out.println(iRef + ": " + versioniRef,); // Array index: unboxing
,

Output:
0: 5
1: .
2: 0

oxing and unboxing in collections/maps:

String, words = new String, ,"aaa", "bbb", "ccc", "aaa",;
Map<String, Integer m = new TreeMap<String, Integer();
for (String word : words) ,
Integer freq = m.get(word);
m.put(word, freq == null . 1 : freq + 1);
,
out.println(m);


The output:
,aaa=2, bbb=1, ccc=1,

In the next example an int is being stored and then retrieved Irom an ArrayList. The J2SE 5.0
leaves the conversion required to transition to an Integer and back to the compiler.
eIore:

ArrayList<Integer list = new ArrayList<Integer();
list.add(0, new Integer(42));
int total = (list.get(0)).intValue();


AIter:
ArrayList<Integer list = new ArrayList<Integer();
list.add(0, 42);
int total = list.get(0);


Here is another sample program Ieaturing autoboxing and unboxing. It is a static Iactory that
takes an int array and returns a List oI Integer backed by the array. This method provides the
Iull richness oI the List interIace atop an int array. All changes to the list write through to the
array and vice-versa:
// List adapter for primitive int array
public static List<Integer asList(final int, a) ,
return new AbstractList<Integer() ,

public Integer get(int i) , return ai,; ,

// Throws NullPointerException if val == null
public Integer set(int i, Integer val) ,
Integer oldVal = ai,;
ai, = val;
return oldVal;
,

public int size() , return a.length; ,
,;
,


Wrappers and primitives comparison:
public class WrappersTest ,
public static void main(String, s) ,
Integer i1 = new Integer(2);
Integer i2 = new Integer(2);
System.out.println(i1 == i2); // FALSE

Integer j1 = 2;
Integer j2 = 2;
System.out.println(j1 == j2); // TRUE

Integer k1 = 150;
Integer k2 = 150;
System.out.println(k1 == k2); // FALSE

Integer jj1 = 127;
Integer jj2 = 127;
System.out.println(jj1 == jj2); // TRUE

int jjj1 = 127;
Integer jjj2 = 127;
System.out.println(jjj1 == jjj2); // TRUE

Integer kk1 = 128;
Integer kk2 = 128;
System.out.println(kk1 == kk2); // FALSE

Integer kkk1 = 128;
int kkk2 = 128;
System.out.println(kkk1 == kkk2); // TRUE

Integer w1 = -128;
Integer w2 = -128;
System.out.println(w1 == w2); // TRUE

Integer m1 = -129;
Integer m2 = -129;
System.out.println(m1 == m2); // FALSE

int mm1 = -129;
Integer mm2 = -129;
System.out.println(mm1 == mm2); // TRUE
,
,

NOTE, certain primitives are always to be boxed into the same immutable wrapper objects.
These objects are then CACHED and REUSED, with the expectation that these are commonly
used objects. These special values are:
O The boolean values true and false.
O The byte values.
O The short and int values between -128 and 127.
O The char values in the range '\u0000' to '\u007F'.
O Character c1 = '\u0000';
O Character c2 = '\u0000';
O System.out.println("c1 == c2 : " + (c1 == c2)); // TRUE !!!
O
O Character c11 = '\u00FF';
O Character c12 = '\u00FF';
O System.out.println("c11 == c12 : " + (c11 == c12)); // FALSE

c1 == c2 : true
c11 == c12 : false

The Iollowing example gives NullPointerException:
Integer i = null;
int j = i; // java.lang.NullPointerException !!!

This example demonstrates methods resolution when selecting overloaded method:
public static void main(String, args) ,
doSomething(1);
doSomething(2.0);
,

public static void doSomething(double num) ,
System.out.println("double : " + num);
,

public static void doSomething(Integer num) ,
System.out.println("Integer : " + num);
,

The output is:
double : 1.0
double : 2.0

Java 5.0 will always select the same method that would have been selected in Java 1.4.
The method resolution inludes three passes:
1. Attempt to locate the correct method WITHOUT any boxing, unboxing, or vararg
invocations.
2. Attempt to locate the correct method WITH boxing, unboxing, and WITHOUT any
vararg invocations.
3. Attempt to locate the correct method WITH boxing, unboxing, or vararg invocations.
$tring
The String class represents character strings. All string literals in Java programs, such as "abc",
are implemented as instances oI this class.
All implemented interIaces: Serializable, CharSequence, Comparable<String.
This method returns the number oI characters in the string as in:
int length ()

This example results in variable x holding the value 8:
String str = "A string";
int x = str.length ();

Removes whitespace Irom the leading and trailing edges oI the string:
String trim ()

This results in the variable str reIerencing the string "14 units":
String string = " 14 units ";
String str = string.trim ();

The Iollowing methods return the index, starting Irom 0, Ior the location oI the given character in
the string. (The char value will be widened to int):
int indexJf (int ch)
int lastIndexJf (int ch)

For example:
String string = "Jne fine day";
int x = string.indexJf ('f');

This results in a value oI 4 in the variable x. II the string holds NO such character, the method
returns -1.
To continue searching Ior more instances oI the character, you can use the method:
indexJf(int ch, int fromIndex)

This will start the search at the IromIndex location in the string and search to the end oI the
string.
The methods:
indexJf (String str)
indexJf (String str, int fromIndex)

provide similar Iunctions but search Ior a sub-string rather than just Ior a single character.
Similarly, the methods:
lastIndexJf (int ch)
lastIndexJf (int ch, int fromIndex)

lastIndexJf (String str)
lastIndexJf (String str, int fromIndex)

search backwards Ior characters and strings starting Irom the right side and moving Irom right to
leIt. (The fromIndex second parameter still counts Irom the leIt, with the search continuing Irom
that index position toward the beginning oI the string).
These two methods test whether a string begins or ends with a particular substring:
boolean startsWith (String prefix)
boolean endsWith (String str)

For example:
String , str = ,"Abe", "Arthur", "Bob",;
for (int i=0; i < str.length (); i++) ,
if (str1.startsWith ("Ar")) doSomething ();
,

The Iirst method return a new string with all the characters set to lower case while the second
returns the characters set to upper case:
String toLowerCase ()
String toUpperCase ()

Example:
String , str = ,"Abe", "Arthur", "Bob",;
for (int i=0; i < str.length(); i++),
if (str1.toLowerCase ().startsWith ("ar")) doSomething ();
,
Related Tags Ior Autoboxing/unboxing oI primitive types :
:t-Bolts of 1ava:
a) 1ava $ - 1ava $ ( 1ava Standard Edition ) provides tools and !s to create diverse
applications. pplications developed with 1ava $ are s:pported by every operating
system, incl:ding Lin:x, Macintosh, $olaris, and Windows.

b) 1ava - 1ava Enterprise Edition specifications based on the fo:ndation framework of
the standard edition. 1ava nterprise dition are the specifications needed to service the
m:lti-tiered environment, to s:pport the enterprise class service oriented architect:re
($) and a lot...............

c) 1ava M - 1ava Micro Edition is an acc:m:lation of 1ava !s :sed to develop micro-
devices applications like mobile phones, !s, TV set-top boxes, game programming. The
platform of micro edition generally consists of an easy :ser interface, a rob:st sec:rity
model and a wide variety of b:ilt-in networks for r:nning 1ava based application.

You might also like