Java is a statically typed language, it requires the user to define the type of the data before declaring the variable (Oracle). Thus, a programmer who may not know about generics will end up re-writing the same class multiply times to create an object of integer, double and string in order to meet an application's requirement.

Therefore, it is important to have a good knowledge of generics in Java. Languages such as JavaScript or Python allow users to define the variable without defining the data type.

As a result, a programmer can use the same class with different data types. However, Java is not that flexible, but the need for flexibility in variable declaration and datatypes has led Java developers to create the generic object, which almost behaves similar to non-statically typed languages.

In this tutorial, we use a generic stack class and data structure to illustrate the benefit of using generics.

A Generic Class can be written once but used multiple times, which is the principle of Don't Repeat Yourself (DRY). Let's review the following generic and non-generic classes.

https://raw.githubusercontent.com/menhaj007/genericStack/main/Car.java

https://raw.githubusercontent.com/menhaj007/genericStack/main/Car1.java

https://raw.githubusercontent.com/menhaj007/genericStack/main/ZipCode.java

To instantiate a generic Java class, add <T>or <E> or any other preferred word or letter next to the class name. For example, public class Car<T>, public class Queue<E> or public class Tree<Node>.

Let's compare the above two samples /(links) classes:

There are two key differences in the above examples. The first difference is that a generic class needs to be instantiated with Object Wrappers such as <Integer>, <Double>, <String>. The other difference is that multiple instances of the same class can be created with different data types in the main method.

On the other hand, in class Car1's variable type must be defined before creating an instance of it. There will be a need for a new class if the datatype for serialCode and weight needs to be changed. Thus, a generic class can save both time and space when used efficiently.

Note: A user can define a generic class with multiple key and value pairs such as HashMap. For instance, public class Zipcode<code, cityName>.

public class ZipCode<code, city> {
    code areaCode;
    city cityName;

    public ZipCode(code areaCode, city cityName) {
        this.areaCode = areaCode;
        this.cityName = cityName;
    }
    public String toString() {
        return "Zip code: " + areaCode + ", City name: " + cityName;
    }

    public static void main(String[] args) {
        ZipCode<Integer, String> alexandria = new ZipCode<>(22304, "Alexandria");
        ZipCode<Integer, String> fairfax = new ZipCode<>(22030, "Fairfax");
        System.out.println(alexandria);
        System.out.println(fairfax);
        ZipCode<Long, String> Himalaya = new ZipCode<>(33939932223L, "Himalaya");
        System.out.println(Himalaya);

    }
}

https://raw.githubusercontent.com/menhaj007/genericStack/main/ZipCode.java

In order to allow a number longer than the integer's capacity, all it needed was to replace <Integer, String> with <Long, String>.

Let's review the Stack Data Structure before implementation. A stack is a Last In First Out (LIFO) data structure (Wikipedia). This means when a programmer decides to design a stack data structure, he/she implements at least the following methods or algorithms:

pop(), push(), top(), isFull(), isEmpty() and size(). One of the commonly used data structures in a stack is an array object. In Java, the size and data type of an array must be defined at the time of instantiation. Otherwise, it will throw error. Let's compare JavaScript's array and Java's Array.

JavaScript: let myArray = []

Java: int[] myArray = new int[10], or data-type[] variable = new data-type[size]

By looking at Java's array implementation, it is clear that if a programmer needs to create an array of strings, then he/she must redo the whole work, unless a generic object is used. In general, datatypes must be statically typed before declaring the variables.

If a programmer doesn't use a generic datatype for implementing a stack data structure, and if the need for having multiple types of the stack or other classes rise, then the programmer has to create multiples of similar stacks or classes.

The followings are sample implementations of integer stack, string stack, and generic stacks:

None
Stack Data Structure

https://raw.githubusercontent.com/menhaj007/genericStack/main/IntStack.java

https://raw.githubusercontent.com/menhaj007/genericStack/main/StringStack.java

https://raw.githubusercontent.com/menhaj007/genericStack/main/Stack.java

https://raw.githubusercontent.com/menhaj007/genericStack/main/Main.java