Profile Photo

Generics in java

Created on: Oct 1, 2024

Java generics is mechanism that allows us to write code that does not care about the type of objects it is handling while at the same time giving enough information to the compiler to preserve type safety.

Generics allow for code reuse and type safety by providing a way to create classes, interfaces, and methods that can work with any data type without sacrificing type checking at compile time.

class Container<T>{ T content; public Container(T content) { this.content = content; } public T getContent() { return content; } public void setContent(T content) { this.content = content; } } public class Hello { public static void main(String[] args) { Container<Integer> integerContainer = new Container<>(10); System.out.println(integerContainer.getContent()); Container<String> stringContainer = new Container<>("Hello world"); System.out.println(stringContainer.getContent()); } }

In above code, there is no restriction on the type of T, so anything can be assigned to it. This is called Unbounded types generics. It give less compile time safety compare to bounded types.

Bounded Type Safety

class BoundedGeneric<T extends Number>{ private T content; public BoundedGeneric(T content) { this.content = content; } public T getContent() { return content; } } public class Hello { public static void main(String[] args) { BoundedGeneric<Integer> integerBoundedGeneric = new BoundedGeneric<>(10); System.out.println(integerBoundedGeneric.getContent()); } }

Multiple generic type

class Pair<K extends Comparable<K>, V extends Number >{ 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; } public void display(){ System.out.println("key "+ key+" value="+ value); } } public class Hello { public static void main(String[] args) { Pair<String, Integer> agePair = new Pair<>("Jodn Doe", 40 ); agePair.display(); Pair<String, Double> salaryPair = new Pair<>("Jodn doe", 400000.00); salaryPair.display(); Pair<Integer, Float> scorePair = new Pair<>(100, 200.0f); scorePair.display(); } }
key Jodn Doe value=40 key Jodn doe value=400000.0 key 100 value=200.0

Generic method

public class Hello { public static <T extends Comparable> int compara(T obj1, T obj2){ return obj1.compareTo(obj2); } public static void main(String[] args) { Integer num1 = 20; Integer num2 = 30; System.out.println("Comparing object res "+ compara(num1, num2)); String str1 = "Hello1"; String str2 = "Hello1"; System.out.println("Comparing sting res "+ compara(str1, str2)); } }
Comparing object res -1 Comparing sting res 0

Another complex example

import java.util.Objects; interface Identifiable { String getId(); String getName(); } class Person implements Comparable<Person>, Identifiable { private String id; private String name; private int age; public Person(String id, String name, int age) { this.id = id; this.name = name; this.age = age; } public String getId() { return id; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Person other) { return Integer.compare(this.age, other.age); } @Override public String toString() { return "Person{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(id, person.id) && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(id, name, age); } } public class Hello { public static <T extends Comparable<T> & Identifiable> String compareObjects(T obj1, T obj2) { int compareResult = obj1.compareTo(obj2); if (compareResult == 0) { return "Objects have equal age but different IDs: " + obj1.getId() + " and " + obj2.getId(); } else if (compareResult < 0) { return obj1.getName() + " is younger than " + obj2.getName(); } else { return obj1.getName() + " is older than " + obj2.getName(); } } public static void main(String[] args) { Person person1 = new Person("1", "Alice", 25); Person person2 = new Person("2", "Bob", 30); System.out.println(compareObjects(person1, person2)); Person person3 = new Person("3", "Charlie", 25); System.out.println(compareObjects(person1, person3)); } }

Example from java collection where generics are used

undefined