dúvida com os genéricos

Oi,

eu tenho um hashMap Mapa que pode conter dois tipos de objectos. ObjA e ObjB. Como faço, usando os genéricos, para dizer que o objecto Mapa pode conter estes dois tipos de objectos ao mesmo tempo?

Será que devo extender o ObjA e o ObjB para uma classe comum? Eu não queria fazer isso. Eu quero considerar estes dois objectos distintos.

Obrigado
Pedro

Se vc quer considerar duas coisas distintas, como vc quer q o Map aceite duas coisas que são diferentes sendo q vc tem q indicar um tipo específio?

Vc tem sim que criar uma classe mais abstrata (num to falando abstract necessariamente) e extender ela, como vc disse.

Ou então fazer uma composição, o ObjB ter uma referencia a ObjA ou vice versa, assim vc pode indicar no map q ele vai guardar um dos dois e o q foi indicado armazena uma referencia ao outro.

Seria isso?

Map<ClasseDoObjA, ClasseDoObjB> meuMap = new HashMap<ClasseDoObjA, ClasseDoObjB>()

Por exemplo:

Map<String, Integer> ages = new HashMap<String, Integer>(); ages.put("Lucas", Integer.parseInt(10)); ages.put("Marcos", Integer.parseInt(19));

sim, pra que um mapa genérico receba duas classes diferentes a solução é essa; estes tais objetos vão precisar sim de uma interface ou ancestral comum, afinal, se vc pensar bem, por que eles estariam juntos se não tivessem alguma semelhança?

crie essa interface ou classe abstrata de uma forma que vc possa fazer as mesmas chamadas, não importanto a implementação.

boa sorte, :smiley:

1 - [quote]
sim, pra que um mapa genérico receba duas classes diferentes a solução é essa; estes tais objetos vão precisar sim de uma interface ou ancestral comum, afinal, se vc pensar bem, por que eles estariam juntos se não tivessem alguma semelhança?
[/quote]

Por acaso a única semelhança entre ObjA e o ObjB é um atributo denominado ipAddress. Daí a minha vontande de considerar ObjA e ObjB objectos sem extensão a uma classe comum.

Mas não é possível ter um mapa que aceite vários tipos de objectos distintos? É claro que terei atenção no código para não haver ClassCastException.

Por exemplo:

public class ClasseA(){...}

public class ClasseB(){...}
Map<String, aceita ClasseA e ClasseB> meuMap = new HashMap<String, aceita ClasseA e ClasseB>()

....

public void addElement(String key, aceita objectos da ClasseA e ClasseB - obj)
{
 meuMap.put(key, obj)
}

2 - Se usar o seguinte na ClasseA e ClasseB não vai permitir realizar o que quero na pergunta 1?:

public class ClasseA()<Elemento>{...}

public class ClasseB()<Elemento>{...}

3 - Qual é o objectivo de se ter classes da seguinte forma:

public class ClasseA()<Elemento>{...}

4 - Alguém pode-me explicar como funcionam os métodos genéricos?

5 - Muitas vezes na api do J2SE encontramos classes da seguinte forma:

Collection<E>
Map<K,V>

Que eu saiba, E, K e V não são nenhuns tipos. Porque razão usa-se este tipo de letras? Será que o uso dessas letras querem dizer outra coisa? Podem-me explicar?

Obrigado,
Pedro

Você pode usar apenas uma superclasse no generic, não duas classes totalmente distintas.

Se a única semelhança é um método, ou você usa dois mapas, ou você usa um tipo de uma superclasse e faz cast. A segunda opção é muito sujeita a erros.

Tem ainda a opção, que já foi dita, de criar uma interface e fazer as classes implementarem. Apenas fica a ressalva de que, se você está utilizando classes da API da Sun ou de terceiros, criar uma subclasse só para ter a implementação dessa interface pode fazer mais mal do que bem.

Você pode escolher qualquer letra para o seu generic.

Entretanto, quando você tem mais de um tipo genérico, é melhor escolher letras que tenham mais significado. No caso do map, escolhem K e V pois se tratam dos tipos de “Key” e “Value”. A letra E é muito usada por indicar “Element”.

Para informações detalhadas sobre os generics, leia o documento:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Mesmo que duas classes tenham apenas UM atributo em comum, você pode fazer ambas implementar uma interface que é só esse tal atributo em comum.

interface Addressable {
    // Este é o acessor do tal atributo em comum. 
    // Acrescente o "putIPAddress" se você precisar dele.
    InetAddress getIPAddress(); 
}
class ClassA extends BlaBleBli implements Addressable {
...
}
class ClassB extends DlaDeDli implements Addressable {
...
}
...
Map<String, Addressable> meuMap = new HashMap <String, Addressable> ();