Cualquier lenguaje de tipado estático tiene un problema y es que dada una estructura de datos generica, debemos programarla n veces como n sea el tipo de datos que queramos usarla.
Una posible solución es tipar esta estructura a object, esto trae con sigo ciertos problemas.
- Se pierde la seguridad por tipo.
- Debemos castear al tipo de la estructura cada vez que consultemos un elemento:
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
A partir de java 5 se introduce el concepto de clases genéricas. Permiten utilizar y programar estructuras genéricas, las cuales se les indica el tipo:
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0); // no cast
Entre las ventajas podemos nombrar:
- Chequeo de tipos
- Se elimina la necesidad de casteos.
- Posibilidades de utilizar y programar algoritmos y estructuras genéricas
- Es muy utilizado en Framework de colecciones de java.
Podemos generar clases genericas:
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
Donde T es el tipo de nuestra clase genérica. Si queremos utilizar esta clase para un tipo determinado:
Box<Integer> integerBox = new Box<Integer>();
integerBox.set(45);
Integer nro = integerBox.get();
Y con el operador diamante:
Box<Integer> integerBox = new Box<>();
integerBox.set(45);
Integer nro = integerBox.get();
Como ven el operador diamante, no es más que no decirle el tipo cuando instancio la clase, porque el compilador lo puede inferir de la declaración. Es eso y un poco de marketing.
Veamos otro ejemplo:
public interface Pair<K, V> {
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair<K, V> {
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
Pair<String, String> p2 = new OrderedPair<String, String>("hello", "world");
OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));
Y podemos tener métodos genéricos:
public class Util {
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
Por ahora eso es todo de generics.
Dejo link: