Read and Sort Data Generically - Generics in Java
Tags: java, algorithms, generics
Published: 2021-08-01 12:45:15

I will demonstrate a Generic Java Class that will **read and write the objects** any type of object passed to it (any **Primitive Datatype or your custom classes** Like Explained in this example)

Consider, you have a Class Named **Students** in which there is **name** and **id** for a student.

Now Also Consider another class named **Employees** which also has **name**, **id** and **workhours**.

Now we want to implement a Generic class which will **automatically writes the object to a file with file name begin the name of the class**. Now if there is already a **.txt** file of that same class then it should **append** the file with given new object.

The Program should also be capable to **read** the required file. The **read()** method will **return** the generic **ArrayList** which we can type **cast** to our required object like if we want to read the Students list stored in txt file then the read() method will return a Generic ArrayList and we can **typecast** it to **Students ArrayList** and Easily Use it.

**Hence Completes our Requirement,**
> *A Program the read and write any type of objects plus it writes the same type objects in their own text files (Appends if already present or create new if object of such type is written for the 1st time) making it awesome code that handles the files automatically.*

# QUICK THINGS TO KNOW BEFORE STARTING
So First I have made two classes named **Students.java** and **Employees.java** and my main class is **Main.java.**

`Main.java is shown at the end of this post, while Student.java &  Employees.java is not shown for the sake of complexity but if you do need to see them.`

> Visit [Here](https://saimhafeez.com/java-section/java-examples/advance/read-and-sort-data-generically-java-generics-saimhafeez-com/) for more detailed explanation with output explanation.

In **Students.java** I have made a **Constructor**, **getters** and **setters** for **name** and **id**

IN Both Classes I Have Made A Method Named **getData()** That Just Displays **The Data (Name, Id, workhours etc)** of our Object.

# Implementing Generic Class

## Making A Generic Class
I have made a class name **GenericRead_Write.java** and I have **parameterized** it by using **<T>**. We also created a field named **object** with **Type T**. Now in **Constructor** I have set the **instance object** with the locally passed **object**. The Purpose of **state** variable is explained in **code**.
```
public class GenericRead_Write<T>{

    T object;
    int state  = 0;

    public GenericRead_Write(T object){
        this.object = object;
    }

    public void write(){/* CODE EXPLAINED NEXT */};
    public ArrayList<T> read(){/* CODE EXPLAINED NEXT */};
}
```

## Generic write() Method
```
public void write(){
        state = 1;
        String fileName = object.getClass().getName() + ".txt";
        ArrayList<T> list = new ArrayList<>();
        list = read();
        list.add(object);
        try {
            FileOutputStream file = new FileOutputStream(fileName);
            ObjectOutputStream outputFile = new ObjectOutputStream(file);
            for (T obj:
                 list) {
                outputFile.writeObject(obj);
            }


        }catch (Exception e){
            JOptionPane.showMessageDialog(null, e.getMessage());
        }
    }
```
### Explanation
`String fileName = object.getClass().getName() + ".txt";`
This basically gets the name of the **object** you passed in Generic Class with appending **.txt** at the end of it. Next we will make a ArrayList with T as type parameter with name list.
> list = read()

At Forth Line we calls the **read()** method to check if there is file with name **fileName** is already present or not. If it is present then we read that file and store objects in list Assuming that there is not file present for Students or Employees [These are two test classes I made for the sake of demonstration] at this point, we add the object passed by the user to the ArrayList named list. And in Try and Catch Block we are make a object of **FileOutStream** with file name being the **filename** (it also automatically creates the file with that name if it is not present) and then we make an object for **ObjectOutputStream** to write the object to file. And finally, By Using Foreach Loop we are writing the object to file. Before compiling, There is no file.
<img src="https://saimhafeez.com/wp-content/uploads/2021/08/1.png" alt="Java-generics-output01-saimhafeez.com">
After Comiling Programs creates a text file with our class name and package name being at start. See Below
<img src="https://saimhafeez.com/wp-content/uploads/2021/08/2.png" alt="Java-generics-output01-saimhafeez.com">

## Generic read() Method
```
public ArrayList<T> read() {
        String fileName = object.getClass().getName() + ".txt";
        ArrayList<T> list = new ArrayList<>();
        try{
            FileInputStream file = new FileInputStream(fileName);
            ObjectInputStream inputFile = new ObjectInputStream(file);
            boolean END_OF_FILE = false;
            while (!END_OF_FILE){
                try {
                    list.add((T) inputFile.readObject());
                }catch (EOFException e){
                    // When reaches END OF FILE we set the Boolean END_OF_FILE to TRUE
                    END_OF_FILE = true;
                }catch (Exception e){
                    JOptionPane.showMessageDialog(null, e.getMessage());
                }
            }

        }catch (FileNotFoundException j){
            if(state == 1){
                // Do Nothing... When state is 1 it means the write method is called
                // Since, the wite method will automatcally create new file is not found
                // So we don't require our program to show exception if read() is called from write()
            }else {
                // When state is 0 means the write() is not called so if file does not exits
                // in this case we show Error Message that file is not found
                JOptionPane.showMessageDialog(null, j.getMessage());
            }

        }catch (Exception e){
            JOptionPane.showMessageDialog(null, e.getMessage());
        }

        return list;
    }
```
### Explanation
First of All this method will return a generic ArrayList so we used `ArrayList<T>` as return type.

Just like Previous we are creating a accurate **fileName** and **ArrayList** named **list**. Now to read objects we will use object of **FileInputStream** and pass it to **objectInputStream**. Now we will make a boolean varibale named **END_OF_FILE** which initially will be **false** now in while loop we can **not (!)** the **END_OF_FILE** So, loop will run and read the objects and store them to **ArrayList**. Now in **catch statement** we can use **EOFException** (END OF FILE Exception) and when we reach the end we can simply put the **END_OF_FILE** equals to **TRUE** Hence Loop will end. Now we can simply return the **list**.

Now at **Main.java** we can access methods of our objects returned by this list by using type **casting**.
<img src="https://saimhafeez.com/wp-content/uploads/2021/08/5.png" alt="Java-read-saimhafeez.com">

#That's it!, for now
*If you have any question, ask me in the comment section.
Visit, [my site](https://www.saimhafeez.com) for more Tutorials and examples*