1// generic methods
2
3public <T> List<T> fromArrayToList(T[] a) {
4 return Arrays.stream(a).collect(Collectors.toList());
5 }
6
7public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) {
8 return Arrays.stream(a)
9 .map(mapperFunction)
10 .collect(Collectors.toList());
11 }
12
13// bounded generics
14
15public <T extends Number> List<T> fromArrayToList(T[] a) {
16 ...
17 }
18
19//multiple bounds
20
21<T extends Number & Comparable>
22
23// upper bound wildcards
24
25public static void paintAllBuildings(List<? extends Building> buildings) {
26 ...
27 }
28
29// lower bound wildcard
30
31<? super T>
1public class Tuple <T> {
2 // the T is a placeholder for any datatype
3 public T leftValue;
4 public T rightValue;
5
6 public Tuple(T leftValue, T rightValue){
7 // again, T is being used as a placeholder for any type
8 this.leftValue = leftValue;
9 this.rightValue = rightValue;
10}
11
12public class Program{
13 public static void main (String args){
14 // And upon using Tuples we can fill in the T from the Tuple class with actual datatypes
15 Tuple <int> intTuple = new Tuple <int>(5, 500)
16 Tuple <String> stringTuple = new Tuple <String> ("Hello", "World")
17
18 // we can even put Tuples inside of Tuples!
19 Tuple<Tuple<int>> metaIntTuple = new Tuple <Tuple <int>> (intTuple, new Tuple <int> (456, 0));
20 }
21}
1static void fromArrayToCollection(Object[] a, Collection<?> c) {
2 for (Object o : a) {
3 c.add(o); // compile-time error
4 }
5}
6
1/*Suppose we want to restrict the type of objects that can be used in the parameterized type, for example in a method that compares two objects and we want to make sure that the accepted objects are Comparables. To declare a bounded type parameter, list the type parameter’s name, followed by the extends keyword, followed by its upper bound, similar like below method.
2
3The invocation of these methods is similar to unbounded method except that if we will try to use any class that is not Comparable, it will throw compile-time error.
4
5Bounded type parameters can be used with methods as well as classes and interfaces.
6
7Java Generics supports multiple bounds also, i.e <T extends A & B & C>. In this case, A can be an interface or class. If A is class then B and C should be an interface. We can’t have more than one class in multiple bounds.*/
8public static <T extends Comparable<T>> int compare(T t1, T t2){
9 return t1.compareTo(t2);
10 }
11
1Java Generic Type Naming convention helps us understanding code easily and having a naming convention is one of the best practices of Java programming language. So generics also comes with its own naming conventions. Usually, type parameter names are single, uppercase letters to make it easily distinguishable from java variables. The most commonly used type parameter names are:
2
3E – Element (used extensively by the Java Collections Framework, for example ArrayList, Set etc.)
4K – Key (Used in Map)
5N – Number
6T – Type
7V – Value (Used in Map)
8S,U,V etc. – 2nd, 3rd, 4th types
1import java.util.Scanner;
2import reader.*;
3
4public class Main {
5 public static void main(String[] args) throws Exception {
6 Scanner scanner = new Scanner(System.in);
7 String filePath = scanner.nextLine().trim();
8 System.out.println("The file path is " + filePath);
9 String type = filePath.substring(filePath.lastIndexOf('.') + 1).replaceAll("\\W", "");
10 System.out.println("The reader type is " + type);
11 AbstractReaderService reader = getReaderService(type);
12 // reader.read(filePath);
13 // reader.printContent();
14
15 }
16
17 private static AbstractReaderService getReaderService (String type) throws Exceptions.TypeNotFoundException {
18 switch (type) {
19 case "txt": return new TxtReaderService();
20 case "json": return new JsonReaderService();
21 default: throw new Exceptions().new TypeNotFoundException("There is no \"" + type + "\" type of reader.");
22 }
23 }
24}
25