generic interface java code example

Example 1: java generics

// generic methods

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

public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) {
	    return Arrays.stream(a)
	      .map(mapperFunction)
	      .collect(Collectors.toList());
	}

// bounded generics

public <T extends Number> List<T> fromArrayToList(T[] a) {
	    ...
	}

//multiple bounds

<T extends Number & Comparable>

// upper bound wildcards

public static void paintAllBuildings(List<? extends Building> buildings) {
	    ...
	}
    
// lower bound wildcard

<? super T>

Example 2: generics Interface in java

/*Suppose we want to restrict the type of objects that can be used in the parameterized type, for example in a method that compares two objects and we want to make sure that the accepted objects are Comparables. To declare a bounded type parameter, list the type parameter’s name, followed by the extends keyword, followed by its upper bound, similar like below method.

The invocation of these methods is similar to unbounded method except that if we will try to use any class that is not Comparable, it will throw compile-time error.

Bounded type parameters can be used with methods as well as classes and interfaces.

Java Generics supports multiple bounds also, i.e <T extends A & B & C>. In this case, A can be an interface or class. If A is class then B and C should be an interface. We can’t have more than one class in multiple bounds.*/
public static <T extends Comparable<T>> int compare(T t1, T t2){
		return t1.compareTo(t2);
	}

Example 3: generics Interface in java

/*We can define our own classes with generics type. A generic type is a class or interface that is parameterized over types. We use angle brackets (<>) to specify the type parameter.

To understand the benefit, let’s say we have a simple class as:*/
package com.journaldev.generics;

public class GenericsTypeOld {

	private Object t;

	public Object get() {
		return t;
	}

	public void set(Object t) {
		this.t = t;
	}

        public static void main(String args[]){
		GenericsTypeOld type = new GenericsTypeOld();
		type.set("Pankaj"); 
		String str = (String) type.get(); //type casting, error prone and can cause ClassCastException
	}
}

Example 4: generics Interface in java

/*In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>(); is valid.*/
package java.lang;
import java.util.*;

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

Example 5: generics Interface in java

/*We know that Java inheritance allows us to assign a variable A to another variable B if A is subclass of B. So we might think that any generic type of A can be assigned to generic type of B, but it’s not the case. Let’s see this with a simple program.

We are not allowed to assign MyClass<String> variable to MyClass<Object> variable because they are not related, in fact MyClass<T> parent is Object.*/
package com.journaldev.generics;

public class GenericsInheritance {

	public static void main(String[] args) {
		String str = "abc";
		Object obj = new Object();
		obj=str; // works because String is-a Object, inheritance in java
		
		MyClass<String> myClass1 = new MyClass<String>();
		MyClass<Object> myClass2 = new MyClass<Object>();
		//myClass2=myClass1; // compilation error since MyClass<String> is not a MyClass<Object>
		obj = myClass1; // MyClass<T> parent is Object
	}
	
	public static class MyClass<T>{}

}

Example 6: generics Interface in java

/*Notice that while using this class, we have to use type casting and it can produce ClassCastException at runtime. Now we will use java generic class to rewrite the same class as shown below.*/
package com.journaldev.generics;

public class GenericsType<T> {

	private T t;
	
	public T get(){
		return this.t;
	}
	
	public void set(T t1){
		this.t=t1;
	}
	
	public static void main(String args[]){
		GenericsType<String> type = new GenericsType<>();
		type.set("Pankaj"); //valid
		
		GenericsType type1 = new GenericsType(); //raw type
		type1.set("Pankaj"); //valid
		type1.set(10); //valid and autoboxing support
	}
}
/*Notice the use of GenericsType class in the main method. We don’t need to do type-casting and we can remove ClassCastException at runtime. If we don’t provide the type at the time of creation, the compiler will produce a warning that “GenericsType is a raw type.

References to generic type GenericsType<T> should be parameterized”. When we don’t provide the type, the type becomes Object and hence it’s allowing both String and Integer objects. But, we should always try to avoid this because we will have to use type casting while working on raw type that can produce runtime errors.

Tip: We can use @SuppressWarnings("rawtypes") annotation to suppress the compiler warning, check out java annotations tutorial.*/

Tags:

Java Example