Java Generics - ashwin-shetty/Documents-Wiki GitHub Wiki

Java Generics

Generics are where datatypes are of different types.

In this example MyCustomList class we pass String and Integer value without any type conversion.

class MyCustomList<T> {
    ArrayList<T> list = new ArrayList<>();

    public void addElement(T element) {
        list.add(element);
    }

    public T get(int index) {
        return list.get(index);
    }
}
        MyCustomList<String> list1 = new MyCustomList();
        list1.addElement("Monika");
        System.out.println(list1.get(0));
        //Result : Monika

        MyCustomList list2 = new MyCustomList();
        list2.addElement(1);
        System.out.println(list2.get(0));
        //Result : 1

Bounded Generics Class (with Extends)

class MyCustomExtendList<T extends  Number> {
    ArrayList<T> list = new ArrayList<>();

    public void addElement(T element) {
        list.add(element);
    }

    public T get(int index) {
        return list.get(index);
    }
}
        MyCustomExtendList<Long> list1 = new MyCustomExtendList();
        list1.addElement(1l);
        System.out.println(list1.get(0));
        //Result : 1

        MyCustomExtendList<Float> list2 = new MyCustomExtendList();
        list2.addElement(3f);
        System.out.println(list2.get(0));
        //Result : 3.0

Generic Methods

public class GenericsWithMethodRunner {

     <X> X doubleValue(X value) {
        return value;
    }

     <X extends List> X dValue(X value) {
        return value;
    }



    public static void main(String[] args) {
        GenericsWithMethodRunner generics = new GenericsWithMethodRunner();

        System.out.println(generics.doubleValue("Monika"));
        System.out.println(generics.doubleValue(2f));

        System.out.println(generics.dValue(Arrays.asList(4,6,8,30)));
        System.out.println(generics.dValue(Arrays.asList(5,"Monika",2f)));

    }

}

Generics With WildCard

Wild card can be used in local and member variables. Producer Extends, Consumer Super

Upper bounded wild card "Producer Extends" - If you need a List to produce T values (you want to read Ts from the list),you need to declare it with ? extends T, e.g. List<? extends Integer>. But you cannot add to this list.

    // Upper Bound is used for logic
    //This method is sum of any list which extends Number class
    // here ? is called as wild card
    static double sumOfNumberList(List<? extends Number> numbers) {
        double sum = 0.0;
        for(Number number:numbers) {
            sum+= number.doubleValue();
        }
        return sum;
    }
        System.out.println(sumOfNumberList(Arrays.asList(4,6,8,30)));
        //Result : 48.0
        System.out.println(sumOfNumberList(Arrays.asList(5,2f)));
        //Result : 7.0

Lower bounded wild card "Consumer Super" - If you need a List to consume T values (you want to write Ts into the list),you need to declare it with ? super T, e.g. List<? super Number>. But there are no guarantees what type of object you may read from this list.

    // it is used to add different subtypes together
    static void addCoupleOfValues(List<? super Number> numbers) {
        numbers.add(1);
        numbers.add(1.0);
        numbers.add(1.0f);
        numbers.add(1L);
    }
   List numbers = new ArrayList<Number>();
   addCoupleOfValues(numbers);
   System.out.println(numbers);
   //Result : [1, 1.0, 1.0, 1]
Note: Commonly used generics is generics with types and generics used with method
⚠️ **GitHub.com Fallback** ⚠️