Generics Basics

Back

Loading concept...

🎁 Java Generics: The Magic Box That Fits Everything!

The Story of the Universal Container

Imagine you have a magical toy box. Not just any boxβ€”a shape-shifting box that becomes exactly what you need it to be.

  • Put in toy cars? It becomes a Car Box πŸš—
  • Put in teddy bears? It becomes a Bear Box 🧸
  • Put in dinosaurs? It becomes a Dino Box πŸ¦–

This magical box is Java Generics!


🌟 Generics Introduction

What Problem Does It Solve?

Before generics, Java had a problem. Picture this:

// The OLD way (before generics)
List myList = new ArrayList();
myList.add("Hello");
myList.add(42);  // Mixing types!

// Getting items back was scary...
String text = (String) myList.get(1);
// CRASH! πŸ’₯ 42 isn't a String!

The problem: You could accidentally mix different things, and Java wouldn’t warn you until your program crashed!

The Solution: Generics!

// The NEW way (with generics)
List<String> myList = new ArrayList<>();
myList.add("Hello");
myList.add(42);  // ❌ ERROR at compile time!
// Java stops you BEFORE the crash!

Think of It This Way

Without Generics With Generics
A plain cardboard box A labeled, organized container
You forget what’s inside You always know what’s inside
Surprises when opening No surprises, ever!

The <T> Symbol

When you see <T>, think of it as a blank name tag:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Box<____>          β”‚
β”‚                     β”‚
β”‚  Fill in the blank! β”‚
β”‚  Box<String>        β”‚
β”‚  Box<Integer>       β”‚
β”‚  Box<Dog>           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

T stands for Type. It’s a placeholder that says: β€œTell me what type you want, and I’ll become that!”


πŸ“¦ Generic Classes

A Generic Class is a class with a type parameter. It’s like a recipe that works with any ingredient you choose.

Your First Generic Class

Let’s build our own magical box:

// The Generic Class
public class Box<T> {
    private T item;

    public void put(T item) {
        this.item = item;
    }

    public T get() {
        return item;
    }
}

Using Your Generic Class

// A box for Strings
Box<String> wordBox = new Box<>();
wordBox.put("Hello");
String word = wordBox.get();

// A box for Numbers
Box<Integer> numberBox = new Box<>();
numberBox.put(42);
Integer num = numberBox.get();

Flow of How It Works

graph TD A["Box&amp;lt;T&amp;gt; - Generic Blueprint"] --> B["Box&amp;lt;String&amp;gt;"] A --> C["Box&amp;lt;Integer&amp;gt;"] A --> D["Box&amp;lt;Dog&amp;gt;"] B --> E["Only Strings allowed!"] C --> F["Only Integers allowed!"] D --> G["Only Dogs allowed!"]

Multiple Type Parameters

What if your box needs to hold two different things? Like a key and a value?

public class Pair<K, V> {
    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() { return key; }
    public V getValue() { return value; }
}

Using it:

Pair<String, Integer> score;
score = new Pair<>("Alice", 100);

String name = score.getKey();    // "Alice"
Integer points = score.getValue(); // 100

Common Type Parameter Names

Letter Meaning Example Use
T Type General purpose
E Element Collections
K Key Maps
V Value Maps
N Number Numeric types

πŸ”§ Generic Methods

Sometimes you don’t need a whole generic classβ€”just one method that works with any type.

The Magic Printer

public class Printer {

    // A generic method
    public static <T> void print(T item) {
        System.out.println(item);
    }
}

Notice the <T> before the return type? That declares the type parameter for this method only!

Using Generic Methods

Printer.print("Hello");     // T is String
Printer.print(42);          // T is Integer
Printer.print(3.14);        // T is Double
Printer.print(new Dog());   // T is Dog

Java figures out the type automatically! This is called type inference.

A Useful Example: Swap

Here’s a method that works with any array:

public static <T> void swap(T[] array,
                            int i, int j) {
    T temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

Using it:

String[] words = {"cat", "dog", "bird"};
swap(words, 0, 2);
// Now: {"bird", "dog", "cat"}

Integer[] nums = {1, 2, 3};
swap(nums, 0, 1);
// Now: {2, 1, 3}

Method vs Class Generics

graph TD A["Generic Class"] --> B["Type parameter for&lt;br/&gt;WHOLE class"] A --> C["Example: Box&amp;lt;T&amp;gt;"] D["Generic Method"] --> E["Type parameter for&lt;br/&gt;ONE method only"] D --> F["Example: &amp;lt;T&amp;gt; void print&#35;40;T x&#35;41;"]

πŸ”Œ Generic Interfaces

An interface can be generic too! It’s like creating a contract that works with any type.

The Comparable Example

Java has a built-in generic interface:

public interface Comparable<T> {
    int compareTo(T other);
}

Implementing a Generic Interface

public class Student
       implements Comparable<Student> {

    private String name;
    private int grade;

    @Override
    public int compareTo(Student other) {
        return this.grade - other.grade;
    }
}

Now students can be sorted by grade!

Creating Your Own Generic Interface

// A container that can store and retrieve
public interface Container<T> {
    void add(T item);
    T remove();
    boolean isEmpty();
}

Implementing it:

public class Stack<T> implements Container<T> {
    private List<T> items = new ArrayList<>();

    public void add(T item) {
        items.add(item);
    }

    public T remove() {
        return items.remove(items.size() - 1);
    }

    public boolean isEmpty() {
        return items.isEmpty();
    }
}

The Power of Generic Interfaces

graph TD A["Container&amp;lt;T&amp;gt; Interface"] --> B["Stack&amp;lt;T&amp;gt;"] A --> C["Queue&amp;lt;T&amp;gt;"] A --> D["PriorityQueue&amp;lt;T&amp;gt;"] B --> E["Stack&amp;lt;String&amp;gt;"] B --> F["Stack&amp;lt;Integer&amp;gt;"]

🎯 Quick Summary

Concept What It Is Example
Generics Type-safe containers List<String>
Generic Class Class with type parameter class Box<T>
Generic Method Method with own type parameter <T> void print(T x)
Generic Interface Interface with type parameter interface Container<T>

πŸ’‘ Why Generics Matter

  1. No More Casting - Java knows the type!
  2. Catch Errors Early - At compile time, not runtime
  3. Reusable Code - Write once, use with any type
  4. Cleaner Code - More readable and maintainable

πŸš€ You Did It!

You just learned the fundamentals of Java Generics!

Think of it this way:

  • Generic Class = A reusable container blueprint
  • Generic Method = A flexible tool that adapts
  • Generic Interface = A universal contract

Now go build your own magical type-safe boxes! πŸ“¦βœ¨

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.