Clicky

Util

Generics

Generics are used to specify a range of types an input can be. They are commonly used in libraries to help with code readability and type safety. It is good practice to use generics when possible.

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Generics<A> {

    public static void main(String[] args) {
        // generic methods
        Generics<Integer> g = new Generics<Integer>();
        List<Integer> genericMethodInt = g.genericMethod(new Integer[]{0, 1, 2, 3, 4, 5});
        List<Double> genericMethodDouble = g.genericMethod(new Double[]{0.1, 1.5, 2.7, 3.2, 4.8, 5.6});

        System.out.print("Integer: ");
        for (Integer integer : genericMethodInt) // 0 1 2 3 4 5
            System.out.print(integer + " ");
        System.out.println();
        System.out.print("Double: ");
        for (Double integer : genericMethodDouble) // 0.1 1.5 2.7 3.2 4.8 5.6
        System.out.print(integer + " ");
        System.out.println();

        // array to list
        System.out.print("Sqrt: ");
        Integer[] array = {1, 4, 9, 16};
        Function<Integer, Double> sqrt = a -> Math.sqrt(a);
        List<Double> result = g.fromArrayToList(array, sqrt);
        result.forEach(e -> System.out.print(e + " ")); // 1.0 2.0 3.0 4.0

        g.fromArrayToList(new Integer[]{1, 2, 3, 4, 5}); // parameter extends Number

        //g.multipleBounds("Wrong Type"); // error // parameter does not extend bounds
        g.multipleBounds(1); // parameter extends Number


        g.upperBoundWildcards(new ArrayList<String>()); // String is hight than Object

        g.lowerBoundWildcard(new ArrayList<Object>()); // Object is lover than Integer
    }

    // generic methods
    public <T> List<T> genericMethod(T[] a) {   
        return Arrays.stream(a).collect(Collectors.toList());
    }

    // array to list
    public /*Don't need A here*/<G> List<G> fromArrayToList(A[] a, Function<A, G> mapperFunction) {
        return Arrays.stream(a)
        .map(mapperFunction)
        .collect(Collectors.toList());
    }

    // bounded generics

    public <T extends Number> List<T> fromArrayToList(T[] a) {
        return Arrays.stream(a).collect(Collectors.toList());
    }

    //multiple bounds

    public <T extends Number & Comparable<T>> void multipleBounds(T boundedParam) {

    }

    // upper bound wildcards

    public void upperBoundWildcards(List<? extends Object> buildings) {

    }

    // lower bound wildcard

    public void lowerBoundWildcard(List<? super A> exaple) {

    }

    //***//Wildcards//***//
    // if you want to be able to pass in List<Integer>, List<Double>, and List<Long>
    // if you try to pass in List<Boolean> you will get an error
    public void upper(List<? extends Number> list) {

    }

    // if you want to be able to pass in List<Integer>, List<Object>, and List<Number>
    // if you try to pass in List<Double> you will get an error
    public void lower(List<? super Integer> list) {

    }

    // can only use methods from the Object class
    public void none(List<?> list) {
        
    }
}