Applying Generics


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Applying Generics

  1. 1. Applying Generics Writing Type-Safe Code
  2. 2. Generic Class or Interface <ul><li>In Java, an Interface or a Class can be declared as taking one or more type parameters. If this is the case, the respective class or the interface is said to be generic. </li></ul><ul><li>Type Parameters are written in angle brackets. It serves a place holder for type arguments. </li></ul><ul><li>Each type parameter is replaced by a type argument when we create an object of the generic type. </li></ul>class X<T1,T2> { private T1 ref1; private T2 ref2; public X(T1 ref1,T2 ref2) { this.ref1 = ref1; this.ref2 = ref2; } public T1 getRef1() { return ref1; } public T2 getRef2() { return ref2; } }
  3. 3. Primary purpose of Java generics <ul><li>While implementing & using Collections framework, We often require to specify that a collection contains elements of a certain type. i.e., homogenous elements </li></ul><ul><li>such as a list of integral values </li></ul><ul><li>a list of strings. </li></ul><ul><li>Is this feasible or desirable to create separate Implementation classes for holding homogenous collections like IntegerList, StringList, FloatList etc? </li></ul><ul><li>Isn’t it good to have a single implementation of the collection class and use it to hold elements of different types? </li></ul><ul><li>implementation of one generic class that can be instantiated for a variety of types. </li></ul>
  4. 4. Prime Benefit <ul><li>Early error detection at compile time. Thus, helps making our code Type Safe. </li></ul><ul><li>It better to get Compile-time errors rather than getting Exceptions at Runtime exceptions. </li></ul><ul><li>In Java, a program is considered type-safe if it compiles without errors and warnings and does not raise any unexpected ClassCastExceptions at runtime. </li></ul>What’s the meaning of Type-safety?
  5. 5. SubTyping & WildCards <ul><li>Objective : </li></ul><ul><li>How subtyping works. </li></ul><ul><li>How wildcards let us use subtyping in connection with generics. </li></ul>
  6. 6. Subtyping and the Substitution Principle <ul><li>As we know one type is a subtype of another if they are related by an extends or implements clause. </li></ul><ul><ul><ul><li>Integer is a subtype of Number </li></ul></ul></ul><ul><ul><ul><li>ArrayList<E> is a subtype of List<E> </li></ul></ul></ul><ul><ul><ul><li>List<E> is a subtype of Collection<E> </li></ul></ul></ul><ul><li>Subtyping is transitive, meaning that if one type is a subtype of a second, and the second is a subtype of a third, then the first is a subtype of the third. </li></ul><ul><li>Substitution Principle : Wherever a value of one type is expected, we may provide a value of any subtype of that type. </li></ul><ul><ul><ul><li>List<Number> list = new ArrayList<Number>(); </li></ul></ul></ul><ul><ul><ul><li>List.add(4); </li></ul></ul></ul><ul><ul><ul><li>List.add(6.7); </li></ul></ul></ul>
  7. 7. Substitution Principle contd. <ul><li>Integer is a subtype of Number. </li></ul><ul><li>Is List<Integer> a subtype of List<Number>? </li></ul><ul><ul><li>List<Integer> ints = new ArrayList<Integer>(); </li></ul></ul><ul><ul><li>ints.add(5); </li></ul></ul><ul><ul><li>ints.add(56); </li></ul></ul><ul><ul><li>List<Number> nums = ints; // is this allowed? </li></ul></ul><ul><ul><li>nums.add(3.14); </li></ul></ul><ul><ul><li>Is substitution principle being applied here? </li></ul></ul><ul><ul><li>Think of Reverse : Is List<Number> a subtype of List<Integer> </li></ul></ul><ul><ul><li>ArrayList<Number> nums = new ArrayList<Number>(); </li></ul></ul><ul><ul><li>nums.add(8); nums.add(6.7); nums.add(9.89f); </li></ul></ul><ul><ul><li>ArrayList<Integer> ints = nums; // ? </li></ul></ul>
  8. 8. Substitution Principle contd. <ul><li>Conclusion : ArrayList<Integer> isn’t a subtype of ArrayList<Number> even if Integer is a subtype of Number. </li></ul><ul><li>Behavior of Arrays : We know </li></ul><ul><ul><ul><ul><li>Integer[] is a subtype of Number[]. </li></ul></ul></ul></ul>
  9. 9. Bounded Type Parameter <ul><li>class GenTest<T extends Number> </li></ul><ul><li>{ </li></ul><ul><li>T[] nums; </li></ul><ul><li>GenTest(T[] arr) </li></ul><ul><li>{ nums = arr; } </li></ul><ul><li>void sum() </li></ul><ul><li>{ </li></ul><ul><li> double sum=0.0; </li></ul><ul><li> for(T v:nums) </li></ul><ul><li> sum+=v.doubleValue(); </li></ul><ul><li> System.out.println(&quot;Sum : &quot;+sum); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>public static void main(String[] args) { Integer ints[] = {7,8,5}; Double d[] = {5.3,7.44,6.008}; Float f[] = {4.3f,1.2f,2.3f}; GenTest<Integer> ref1 = new GenTest<Integer>(ints); GenTest<Double> ref2 = new GenTest<Double>(d); GenTest<Float> ref3 = new GenTest<Float>(f); ref1.sum(); ref2.sum(); ref3.sum(); }
  10. 10. WildCard (?) <ul><li>Purpose : </li></ul><ul><li>Sometimes It’s desirable to have lists to behave more like arrays, in that we want to accept not only a list with elements of a given type, but also a list with elements of any subtype of a given type. </li></ul><ul><li>Types : 2 </li></ul><ul><ul><ul><li>Wildcard with extends ? extends E </li></ul></ul></ul><ul><ul><ul><li>Wildcard with super ? super E </li></ul></ul></ul>
  11. 11. Using ? extends T <ul><li>Think of the following: </li></ul><ul><ul><ul><li>interface Collection<E> { </li></ul></ul></ul><ul><ul><ul><li>... </li></ul></ul></ul><ul><ul><ul><li>public boolean addAll(Collection<? extends E> c); </li></ul></ul></ul><ul><ul><ul><li>... </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><li>Situation : </li></ul><ul><li>We’ve a list of integers and we want to add this list in the list of floats. </li></ul><ul><ul><ul><li>OR We want to add all of the members of one collection to another collection: </li></ul></ul></ul><ul><li>Possibilities : 2 </li></ul><ul><ul><ul><li>It’s OK to add all elements of a collection whose type is E. </li></ul></ul></ul><ul><ul><ul><li>It’s also OK to all elements of a collection which are subtypes of E. </li></ul></ul></ul>
  12. 12. Using ? extends T contd. <ul><li>ArrayList<Number> nums = new ArrayList<Number>(); </li></ul><ul><li>ArrayList<Integer> ints = new ArrayList<Integer>(); </li></ul><ul><li>ints.add(4); ints.add(60); ints.add(45); </li></ul><ul><li>ArrayList<Double> dbls = new ArrayList<Double>(); </li></ul><ul><li>dbls.add(3.4); dbls.add(5.22); dbls.add(12.33); </li></ul><ul><li>nums.addAll(ints); </li></ul><ul><li>nums.addAll(dbls); </li></ul><ul><li>Points to understand : </li></ul><ul><li>ArrayList<Integer> is a subType of ArrayList<? extends Number>. </li></ul><ul><li>ArrayList<Double> is a subType of ArrayList<? extends Number>. </li></ul>
  13. 13. Using ? extends T contd. <ul><li>ArrayList<Integer> ints = new ArrayList<Integer>(); </li></ul><ul><li>ints.add(45); </li></ul><ul><li>ints.add(0); </li></ul><ul><li>ints.add(786); </li></ul><ul><li>ArrayList<? Extends Number> nums = ints; // is this OK? </li></ul><ul><li>nums.add(4.5); // is this OK? </li></ul><ul><li>Points to Understand : </li></ul><ul><li>ArrayList<Number> isn’t a supertype of ArrayList<Integer> but </li></ul><ul><li>ArrayList<? extends Number> is a supertype of ArrayList<Integer> </li></ul>Always Remember if a structure contains elements with a type of the form ? extends E, we can get elements out of the structure, but we cannot put elements into the structure.
  14. 14. ? super T <ul><li>Situation : </li></ul><ul><li>We want to copy all elements from a List into another List. </li></ul><ul><li>Think of the following : </li></ul><ul><li>void copy(List<? super T> dst, List<? extends T> src) </li></ul><ul><li>{ </li></ul><ul><li>for (int i = 0; i < src.size(); i++) </li></ul><ul><li>{ </li></ul><ul><li> dst.set(i, src.get(i)); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>? super T means that the destination list may have elements of any type that is a supertype of T. </li></ul>
  15. 15. ? super T contd. <ul><li>Think of the following : </li></ul><ul><li>void copy(List<T> dst, List<T> src) </li></ul><ul><li>void copy(List<T> dst, List<? extends T> src) </li></ul><ul><li>void copy(List<? super T> dst, List<T> src) </li></ul><ul><li>void copy(List<? super T> dst, List<? extends T> src) </li></ul><ul><li>Conclusion : </li></ul><ul><li>Always use wildcards in a signature if possible, since this permits the widest range of calls. </li></ul>
  16. 16. Get & Put Principle <ul><li>Where to use ? extends T ? </li></ul><ul><li>Where to use ? super T? </li></ul><ul><li>Where we shouldn’t use wildcard at all? </li></ul><ul><li>Use an extends wildcard when only getting values out of a structure is needed. </li></ul><ul><li>Use a super wildcard when only putting values into a structure is needed. </li></ul><ul><li>Don't use a wildcard when both get and put are required. </li></ul>
  17. 17. Are the following code snippets correct? <ul><li>ArrayList<Integer> i; </li></ul><ul><li>i = new ArrayList<Integer>(); </li></ul><ul><li>i.add(6); </li></ul><ul><li>i.add(89); </li></ul><ul><li>ArrayList<? extends Integer> al = i; </li></ul>ArrayList<Number> i; i = new ArrayList<Number>(); i.add(6.7); i.add(89); ArrayList<? super Integer> al = i; Test your understanding Is ArrayList<String> and ArrayList<? extends String> same?
  18. 18. Comparison of Arrays & Lists <ul><li>Array subtyping is covariant, meaning that type S[] is considered to be a subtype of T[] whenever S is a subtype of T. </li></ul><ul><li>Integer ints[] = new Integer[]{1,2,4,52}; </li></ul><ul><ul><li>Number[] nums = ints; </li></ul></ul><ul><ul><li>nums[0]=4.5; </li></ul></ul><ul><ul><li>The subtyping relation for generics is invariant, meaning that type List<S> is not considered to be a subtype of List<T>. </li></ul></ul><ul><ul><li>List<Integer> ints = new ArrayList<Integer>(); </li></ul></ul><ul><ul><li>ints.add(7); ints.add(67); </li></ul></ul><ul><ul><li>List<Number> nums = ints; </li></ul></ul><ul><ul><li>nums.put(2, 3.14); </li></ul></ul><ul><ul><li>How can we add covariant nature to generics? </li></ul></ul>
  19. 19. Comparison & Bounds <ul><li>java.lang.Comparable<T> </li></ul><ul><li>public int compareTo(T o); </li></ul><ul><li>An object belonging to a class can only be compared with an object belonging to the same class. For instance, Integer implements Comparable<Integer>: </li></ul><ul><li>Integer a=0,b=1; </li></ul><ul><li>a.compareTo(b); // returns -1 </li></ul><ul><li>String s1 =“yahoo”; </li></ul><ul><li>String s2 = “google”; </li></ul><ul><li>s1.compareTo(s2); // returns a +ve value </li></ul>
  20. 20. Maximum of a Collection <ul><li>public static <T extends Comparable<T>> T max(Collection<T> coll) </li></ul><ul><li>{ </li></ul><ul><li>T candidate = coll.iterator().next(); </li></ul><ul><li>for (T elt : coll) { </li></ul><ul><li>if (candidate.compareTo(elt) < 0) candidate = elt; </li></ul><ul><li>} </li></ul><ul><li>return candidate; </li></ul><ul><li>} </li></ul><ul><li>Here max can return any type T such that T is a subtype of Comparable<T>. i.e., T is bounded by Comparable<T>. </li></ul><ul><li>List<Integer> ints = Arrays.asList(0,1,2); </li></ul><ul><li>List<String> strs = Arrays.asList(&quot;zero&quot;,&quot;one&quot;,&quot;two&quot;); </li></ul><ul><li>Is the following code legal? </li></ul><ul><li>List<Number> nums = Arrays.asList(0,1,2,3.14); </li></ul><ul><li>Number n = Collections.max(nums) == 3,14; </li></ul>
  21. 21. Comparison <ul><li>Array </li></ul>
  22. 22. sts <ul><li>Array subtyping is covariant, meaning that type S[] is considered to be a subtype </li></ul>