Generics List

9 respostas
LPJava

ae pessoal o uso de genericos eh apenas para List? fiquei nessa duvida tinha uma questao que tinha Set s = new TreeSet();.
achei que podeiria usar generics… mais parece que nao pode ou pode?

9 Respostas

nbluis

Nem perto, são sim muito usadas em listas, mas isso por que elas implementam o generics no codigo.
Da mesma maneira que qualquer classe pode utilizar para dar ao programador a opotunidade de especializar suas classes.

Exemplo simples, na implementação do arrayList do java 1.5

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{

    public boolean add(E o) {
	ensureCapacity(size + 1);  // Increments modCount!!
	elementData[size++] = o;
	return true;
    }
    public void add(int index, E element) {
	if (index &gt size || index &lt 0)
	    throw new IndexOutOfBoundsException(
		"Index: "+index+", Size: "+size);

	ensureCapacity(size+1);  // Increments modCount!!
	System.arraycopy(elementData, index, elementData, index + 1,
			 size - index);
	elementData[index] = element;
	size++;
    }

    public E remove(int index) {
	RangeCheck(index);

	modCount++;
	E oldValue = elementData[index];

	int numMoved = size - index - 1;
	if (numMoved &gt 0)
	    System.arraycopy(elementData, index+1, elementData, index,
			     numMoved);
	elementData[--size] = null; // Let gc do its work

	return oldValue;
    }

}

Como pode ver nos metodos add e remove do arrayList usado o tipo generico E(declarado na classe) para referenciar seus objetos.Logo quando fazemos - ArrayList<String> - estamos dizenos que E será sempre string e a JVM o tratará de tal maneira.

Mas nada impede que seja usado da maneira que quiser, como no codigo que escrevi a pouco.

public class Teste<T> {
     private T generico;
 
     public T getGenerico() {
         return this.generico;
     }
     public void setGenerico(T generico) {
         this.generico = generico;
     }
 }
public static void main(String[] args) {
     Teste<String> teste = new Teste<String>();
     teste.setGenerico("classe generica");
     System.out.println(teste.getGenerico());
  }

Simplificando, generics tem como caracteristica dar suporte a especialização de seus objetos em tempo ainda de compilação.
Isso facilita muito, em alguns casos quando temos mais pessoas trabalhando encima do mesmo código ou até quando escrevemos API’s que serão usadas por outros desenvolvedores trazendo segurança na implementação.

Espero ter ajudado.

Até mais …

LPJava

isso compila:

Set s = new TreeSet();
s.add("3");
s.add(5);
...

tinha uma questao dessa no livro da kathy ai achei que compilar ja que nao especifiquei o tipo para esse conjunto… mais ela disse que nao ia compilar pq passei um int ai…estranho isso… :?

nbluis

Compila sim, mas isso é outro caso.
No Java 5, outra mudança na codificação no código é o autoboxing.

Observe que o metodo add de seu Set recebe por parametro um Object.

Até o Java 1.4 isso não era possivel, mas em Java 5, quando referenciamos um tipo promitivo ao que deveria ser um object implicitamente a JVM trata como se este fosse um objeto Wrapper do mesmo tipo primitivo.

Logo, quando fazemos:

Set s = new TreeSet();
s.add("3");
s.add(5);

É interpretado pela JVM como: Set s = new TreeSet(); s.add("3"); s.add(new Integer(5));
O que o torna um objeto e valido para a adição.

Para mais referencias veja sobre autoboxing e unboxing de Java 5
Link: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.htm

Até mais…

LPJava
public static void before(){
Set s = new TreeSet();
s.add("2");
s.add(3);
Iterator it = s.iterator();
while(it.hasNext())
System.out.print(it.next());
}

pg352 - port resposta - letra E - "lança uma exceção ".
Resposta da kathy - Não é possivel colocar String e ints no mesmo TreeSet. Sem os genericos o compilador nao em como sber qual tipo apropriado para TreeSet em questao entao ele permite que tudo compile. no tempo de exceucao o TreeSet tentara classificar os elementos a medida que eles sao adicionados e quando tentar comparar um Integer com String lançara uma ClassCastException.

bom ai fico na duvida ele lanca uma execação devido o TreeSet nao ter uma classificacao?

nbluis

A bom, dai sim…
Me desculpe…

Não levei em contai isso…
Mas como o proprio diz, esse objeto nao trata isso em tempo de compilação…

Bem pra te dizer a verdade… o que tem é um IF lá que trata isso e lança a
exceção… mas blza…
Dai sim …

O que acontece é que se tu fizer TreeSet<Integer>.
Em tempo de compilação isso será tratado pela JVM.

Valeu.

LPJava

mais a duvida eh… em um TreeSet tenho q ter do mesmo tipo String, Integer? mesmo que nao declare o tipo do conjunto?

ViniGodoy

Sim. Ou tipos que sejam comparáveis entre si.

O problema não está nos generics, mas no fato do TreeSet usar um Comparable (ou Comparator) para ordenar seus elementos. Se você escrever um Comparator que compare String e Integer entre si, o TreeSet funcionará para os dois tipos de dados. Por exemplo, tente usar esse comparator:

public class ObjectComparator implements Comparator<Object> {
      public int compareTo(Object o1, Object o2) {
           return Collator.compareTo(o1.toString(), o2.toString());
      }
}

TreeSet t1 = new TreeSet(new ObjectComparator());
t1.add("5");
t2.add(3);

E o TreeSet funcionará.

LPJava

o uso ainda desses metodos me atrapalha :frowning:

nbluis

Cara nao entendi ainda que tipo de duvidas tu ta tendo.

Uma coisa é quanto a implementaçao de seu TreeSet, e outra coisa totalmente diferente é o conceito de Generics.

Eis um link que eu havia passado em outro tópico que abrange se não tudo quase tudo sobre a utilização de generics.

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Talvez ajude a esclarecer.

Até mais…

Criado 18 de fevereiro de 2007
Ultima resposta 18 de fev. de 2007
Respostas 9
Participantes 3