150 likes | 367 Views
Generic Java Classes. Implementing your own generic classes. ArrayList vs. ArrayList <E> ( or LinkedList vs. LinkedList <E>). JDK 1.4 ( deprecated ): To declare an ArrayList that can contain any datatype : ArrayList someList ;
E N D
Generic Java Classes Implementing your own generic classes CS-2851 Dr. Mark L. Hornick
ArrayList vs. ArrayList<E>( or LinkedList vs. LinkedList<E>) JDK 1.4 (deprecated): To declare an ArrayList that can contain any datatype:ArrayListsomeList; You’ll get a warning if you do this (not an error) – don’t use this approach! JDK 1.5 and later: To declare an ArrayList that can contain only Double’s:ArrayList<Double> salaryList; CS-2851 Dr. Mark L. Hornick
Generics – new to J2SE 5.0/JDK 1.5 Eclipse must be configured to use JDK 1.5 or 1.6 • you should have 1.6 on your PC CS-2851 Dr. Mark L. Hornick
Generic ArrayList<E> ArrayList<Double> salaryList = new ArrayList<Double>(); E specifies the specific type of data that the ArrayList can manage • You must substitute a class name for E This creates an instance, salaryList, of the ArrayList collection class. The elements in salaryList must be (references to) Doubles. Q: Why do we have to use ArrayList<Double>? Can’t we just use ArrayList<double>? A: No. The generic type E must represent a class, not a primitive. Double is a wrapper class that just represents a double primitive. CS-2851 Dr. Mark L. Hornick
Wrapper-to-primitive type conversion is done automatically through boxing and unboxing Example: You want to insert a double value into an ArrayList<Double> at index 30:salaryList.add(30, 40000.00); // works!! This is called boxing: The automatic conversion of a primitive double value (40000.00) to the appropriate Double wrapper object To retrieve the value, no explicit cast is needed: double pay = /*(double)*/ salaryList.get(30); This is because although the get() method returns a Double, a Doublecan be automatically converted to a double primitive type. This is called unboxing. CS-2851 Dr. Mark L. Hornick
Datatype parameter placeholders appear in the definition of classes and interfaces public class ArrayList<E> {…} • E (for “Element”) is a type parameter • E is not a keyword, just a placeholder • The letter T is also used as a placeholder • But you can use any (non-keyword) placeholder name • E and T are commonly-used symbols Generics allow you to create a class template that can use different types of objects when instantiated CS-2851 Dr. Mark L. Hornick
Writing your own generic class Consider a class that deals with intspublic class Maxinator { public intgetMaxValue(int a, int b) {int max=0; int result = a-b; if( result > 0 ) max=a; else if( result < 0 ) max=b; else // a and b are the same max=a; return max; } } CS-2851 Dr. Mark L. Hornick
Next, replace int with a generic placeholder Typically, we use the letter E:public class Maxinator<E> { public E printMaxValue(Ea, E b) {E max=0; E result = a-b; // any issues here?? if( result > 0 ) max=a; else if( result < 0 ) max=b; else // a and b are the same max=a; return max; } } CS-2851 Dr. Mark L. Hornick
The compiler doesn’t “know” what datatypeE represents However, we can specify that E must be a subclass of Number (the superclass of Double, Integer, Float, etc).public class Maxinator<E extends Number> { public printMaxValue(E a, E b) { int max=0; int result = a.intValue() – b.intValue(); // all Numbers support the intValue() method if( result > 0 ) max=a; else if( result < 0 ) max=b; else // a and b are the same max=a; return max; } } CS-2851 Dr. Mark L. Hornick
So far, we have limited our Maxinator class to handle subtypes of Number What if we wanted to allow it to compare other datatypes, like Strings and Students?? • We need another way to compare the objects, regardless of the datatype represented by E The Comparable<E> interface is the key to doing this for any datatype represented by E. CS-2851 Dr. Mark L. Hornick
The Comparable<E> interfacein the java.lang package This interface defines a single method:intcompareTo(E o) // returns -1, 0, or 1 This method compares this object (the one invoking the compareTo() method) to another object of the same datatype (the object represented by o) Many datatypes already implement Comparable: String msg = “Hello”;int result = msg.compareTo(“hello”); // returns 1 Double x = 3.0; result = x.compareTo(4.0); // returns -1result = x.compareTo(3.0); // returns 0 CS-2851 Dr. Mark L. Hornick
We can specify that the class represented by E must implement the Comparable<E> interface Any class E that implements Comparable contains the compareTo() method!!public class Maxinator<E extends Comparable<E>> { public printMaxValue(E a, E b) {int max=0; int result = a.compareTo(b); // returns -1, 0, or 1 if( result > 0 ) max=a; else if( result < 0 ) max=b; else // a and b are the same max=a; return max; } } CS-2851 Dr. Mark L. Hornick
Writing Generic Classes • Write the basic class using a simple type • e.g. int • Test it using a test program • Make sure it works • Replace the simple type identifier with E • Or other generic type name • Add the generic suffix • public class MyGenericClass<E> CS-183Dr. Mark L. Hornick
Using Generic Classes • Declare the specific class using a specific type • MyGenericClass<Integer> • MyGenericClass<String> • MyGenericClass<Student> • Test it using a test program • Make sure it still works All specific types (Integer, String, Student) must support the same methods, (e.g. compareTo()) CS-183Dr. Mark L. Hornick