Created
February 13, 2019 18:44
-
-
Save udoyen/ccf264f077e5b54b553729a43bf90511 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Java Paramter Type Names | |
E – Element (used extensively by the Java Collections Framework, for example ArrayList, Set etc.) | |
K – Key (Used in Map) | |
N – Number | |
T – Type | |
V – Value (Used in Map) | |
S,U,V etc. – 2nd, 3rd, 4th types | |
// Generic Method | |
public class GenericsMethods { | |
//Java Generic Method | |
public static <T> boolean isEqual(GenericsType<T> g1, GenericsType<T> g2){ | |
return g1.get().equals(g2.get()); | |
} | |
public static void main(String args[]){ | |
GenericsType<String> g1 = new GenericsType<>(); | |
g1.set("Pankaj"); | |
GenericsType<String> g2 = new GenericsType<>(); | |
g2.set("Pankaj"); | |
boolean isEqual = GenericsMethods.<String>isEqual(g1, g2); | |
//above statement can be written simply as | |
isEqual = GenericsMethods.isEqual(g1, g2); | |
//This feature, known as type inference, allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets. | |
//Compiler will infer the type that is needed | |
} | |
} | |
// Generic Interface | |
public interface Comparable<T> { | |
public int compareTo(T o); | |
} | |
// Generic Class | |
public class GenericsType<T> { | |
private T t; | |
public T get(){ | |
return this.t; | |
} | |
public void set(T t1){ | |
this.t=t1; | |
} | |
public static void main(String args[]){ | |
GenericsType<String> type = new GenericsType<>(); | |
type.set("Pankaj"); //valid | |
GenericsType type1 = new GenericsType(); //raw type | |
type1.set("Pankaj"); //valid | |
type1.set(10); //valid and autoboxing support | |
} | |
} | |
// Generic Bounded Type Parameters | |
public static <T extends Comparable<T>> int compare(T t1, T t2){ | |
return t1.compareTo(t2); | |
} | |
// Java Generics and Inheritance | |
public class GenericsInheritance { | |
public static void main(String[] args) { | |
String str = "abc"; | |
Object obj = new Object(); | |
obj=str; // works because String is-a Object, inheritance in java | |
MyClass<String> myClass1 = new MyClass<String>(); | |
MyClass<Object> myClass2 = new MyClass<Object>(); | |
//myClass2=myClass1; // compilation error since MyClass<String> is not a MyClass<Object> | |
obj = myClass1; // MyClass<T> parent is Object | |
} | |
public static class MyClass<T>{} | |
} | |
// Java Generic Classes and Subtyping | |
interface MyList<E,T> extends List<E>{ | |
} | |
// Java Generics Wildcards | |
//Question mark (?) is the wildcard in generics and represent an unknown type. The wildcard can be used as the type of a parameter, field, | |
//or local variable and sometimes as a return type. We can’t use wildcards while invoking a generic method or instantiating a generic class. | |
//In following sections, we will learn about upper bounded wildcards, lower bounded wildcards, and wildcard capture. | |
//Java Generics Upper Bounded Wildcard | |
//Upper bounded wildcards are used to relax the restriction on the type of variable in a method. | |
//Suppose we want to write a method that will return the sum of numbers in the list, so our implementation will be something like this. | |
public static double sum(List<Number> list){ | |
double sum = 0; | |
for(Number n : list){ | |
sum += n.doubleValue(); | |
} | |
return sum; | |
} | |
// Now the problem with above implementation is that it won’t work with List of Integers or Doubles because we know that List<Integer> and | |
//List<Double> are not related, this is when upper bounded wildcard is helpful. We use generics wildcard with extends keyword and the upper | |
//bound class or interface that will allow us to pass argument of upper bound or it’s subclasses types. | |
The above implementation can be modified like below program. | |
public class GenericsWildcards { | |
public static void main(String[] args) { | |
List<Integer> ints = new ArrayList<>(); | |
ints.add(3); ints.add(5); ints.add(10); | |
double sum = sum(ints); | |
System.out.println("Sum of ints="+sum); | |
} | |
public static double sum(List<? extends Number> list){ | |
double sum = 0; | |
for(Number n : list){ | |
sum += n.doubleValue(); | |
} | |
return sum; | |
} | |
} | |
// Sometimes we have a situation where we want our generic method to be working with all types, in | |
//this case unbounded wildcard can be used. Its same as using <? extends Object>. | |
public static void printData(List<?> list){ | |
for(Object obj : list){ | |
System.out.print(obj + "::"); | |
} | |
} | |
// Suppose we want to add Integers to a list of integers in a method, we can keep the argument type as List<Integer> | |
//but it will be tied up with Integers whereas List<Number> and List<Object> can also hold integers, so we can use lower | |
//bound wildcard to achieve this. We use generics wildcard (?) with super keyword and lower bound class to achieve this. | |
// We can pass lower bound or any super type of lower bound as an argument in this case, java compiler allows to | |
//add lower bound object types to the list. | |
public static void addIntegers(List<? super Integer> list){ | |
list.add(new Integer(50)); | |
} | |
//Subtyping using Generics Wildcard | |
List<? extends Integer> intList = new ArrayList<>(); | |
List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment