Perguntinha para quem vai fazer certificação!

public class Test {   
 public static void main(String[]args){        
      Set sst=new HashSet<Integer>();       
      sst.add(new String("sdlkfj"));        
      sst.add(new Animal());        
     System.out.println(sst);    
}
}

class Animal {}

Para quem está estudando para a certificação … Esse código compilar ou não ??
Tenho certeza que vão matar logo de primeira os caras aqui são feras!!!

Compila…

A declaração da variável não utiliza Generics, portanto tu pode colocar o que tu quiser ali…

Abraços

Pra ficar mais interessante, vc pode perguntar se isso compila e executa com sucesso (essa tb é fácil, mas tem apenas um detalhe a mais):

public class Test {   
 public static void main(String[]args){        
      Set sst=new TreeSet<Integer>();       
      sst.add(new String("sdlkfj"));        
      sst.add(new Animal());        
     System.out.println(sst);    
}
}

class Animal {}

compila só que lança um classCastException pois os tipos são diferente não tendo como eles se ordenarem é isso Rafael ??

É isso ae, Raff.

Se a classe Animal implementar Comparator, provavelmente o que irá ocorrer é algum erro de runtime (como uma ClassCastException) dentro do método compare da classe Animal - isso porque o método compare irá tentar comparar um Integer com um Animal. Pode também ocorrer um ClassCastException na classe String, método compare - nesse caso, porque não é possível comparar uma String com um Animal. Isso depende da ordem de inserção dos dados dentro do TreeSet.

Se a classe Animal não implementar Comparator, então ocorrerá uma ClassCastException porque Animal não implementa Comparator, portanto não podemos chamar seu método compare.

ele compila normalmente… e executa devido o tipo desse conjunto nao existir… em Collection ele nao olha o tipo do objeto agora quando vc for iterar esse conjunto sem o cast nao compila e com o cast pode lancar uma excecao.
Bom no caso do RafaelVS se nao estou enganado nao compila pq TreeSet nao aceita tipos diferentes mesmo se vc nao declarar um tipo para o conjunto… TreeSet e TreeMap todos os objetos devem ser do mesmo tipo ja q ele sao classificados.

LPJava na verdade compila sim no caso do RafaelVS o que ocorre é uma exceção !!!

rpz é verdade o que nao compila assim é o TreeMap… rpz é uma viajem isso… maior decoreba sou pessimo de decoreba…

import java.util.*;
class DuvTre{
	public static void main(String arg[]){
	TreeMap ts = new TreeMap();
		ts.add(new Integer(10));
		ts.add(new String("camilo"));

}
}

[quote=LPJava]rpz é verdade o que nao compila assim é o TreeMap… rpz é uma viajem isso… maior decoreba sou pessimo de decoreba…

import java.util.*;
class DuvTre{
	public static void main(String arg[]){
	TreeMap ts = new TreeMap();
		ts.add(new Integer(10));
		ts.add(new String("camilo"));

}
}

[/quote]

Esse seu codigo aih nao compila pelo fato de ser TreeMap e tipos diferentes nao… ele nao compila por dois motivos:

  1. TreeMap nao tem metodo add
  2. O método correto, put, recebe dois argumentos Object

O codigo a seguir compila e roda perfeitamente (mesmo os tipos dos valores sendo diferentes):

TreeMap ts = new TreeMap();
ts.put("chave1",new Integer(10));
ts.put("chave2",new String("camilo"));
//ts.put(new Integer(10),new Integer(10)); //Linha 1

Se Linha 1 for descomentada, compilará mas causará ClassCastException, pois a regra que serve para os elementos de um TreeSet (não pode ter tipos diferentes) serve para as chaves de um TreeMap.

Mas é claro camilo que não compila ai: Motivo…
A classe TreeMap não implementa Collection então ela não tem o metodo add e sim put :smiley:

TreeMap mapa  = new TreeMap();
mapa.put(1, "Rafael");
map.put(2, "Durelli");

esse ai compila e executa normal… pois TreeMap ordena utilizando a KEy portanto a Key tem que ser do mesmo tipo nesse caso Integer.

TreeMap mapa = new TreeMap();
mapa.put(1, "Rafael");
mapa.put(2.0, "Durelli");

isso tbm compila normal, mas lançara um ClassCastException pois os valores da chaves são diferentes…

rpz… eu acho q hj eu fumei alguma coisa… so pode :x uhauh aonde achei esse add? hehe eu quis dizer foi a ideia TreeMap… nao aceitar tipo diferentes… mesmo que vc nao declare o tipo na construção do conjunto… aff… hehe :smiley:

eita duplicou o posts :frowning:

Ainda assim n está bem correto, pois os valores pode ter tipos diferentes. Apenas as chaves devem ter o mesmo tipo.

Ainda assim n está bem correto, pois os valores pode ter tipos diferentes. Apenas as chaves devem ter o mesmo tipo.[/quote]

é isso que tentei falar… o que importa é o tipo… e nao os valores…rpz ta lento aki o guj… ai para abrir uma pagina é 30 minutos… qdoi clico em enviar… mais 30 para eu ver se o pots foi…

Como o RafaelVs falow :smiley: isso para Map néh rafa… para set os valores tem que ser iguais porque senão lancará um ClassCastException: RafaelVs a minha duvida é a seguinte em um HashSet e um HashMap eu posso tem valores diferentes, tipo como chave pode ser um Integer outro Double…
Não sei se eu foi claro na duvida …

Raff, pensando nas interfaces em geral (Map e Set), você pode ter chaves/valores com tipos diferentes.

Apenas nos casos das implementações TreeSet e TreeMap é que há essa restrição. Isso porque eles utilizam o método compareTo() da clase da chave/valor (que por sua vez deve implementar a interface Comparable) pra poder fazer a ordenação (ou o método compare, caso tenha sido informado umComparator no momento da instanciação da coleção). E nesse método, dependendo da implementação, ele tenta fazer um cast para o tipo da chave/valor (esse cast existe pelo menos nas classes mais comuns, String, Integer, Long, etc…) . Então, quando os tipos são diferentes, acaba sendo lançado um ClassCastException.

Já nos casos simples, HashSet, LinkedHashSet, HashMap, Hashtable essa exceção não é lançada pois não existe essa tentativa de cast e, por isso, não há restrição entre os tipos das chaves/valores.

Isso significa que, na verdade, embora estejamos falando que as classes da chave/valor devem ter o mesmo tipo para nao ser lancado ClassCastException em tempo de execucao, isso não eh 100% correto. Isso soh eh verdade se a implementacao do metodo compare da classe que esta sendo inserida tenta fazer um cast (o que acontece para a maioria das classes testadas no exame) ou se o Comparator informado no momento q instanciou a coleção tenta fazer o cast.

Isso quer dizer que se vc criar duas classes diferentes que implementam Comparable e simplesmente retornam um numero fixo 1, por exemplo, e vc tentar colocar elementos dessa classe em um TreeSet, mesmo sendo de tipos diferentes, não será lançado ClassCastException.

Segue um exemplo que executa normal:

public class Test {

import java.util.TreeSet;

	public static void main(String[] args) {
		TreeSet treeSet = new TreeSet();
		treeSet.add(new A());
		treeSet.add(new B());
		System.out.println(treeSet);
	}
	
	static class A implements Comparable {
		public int compareTo(Object o) {
			return 1;
		}
	}
	
	static class B implements Comparable {
		public int compareTo(Object o) {
			return 1;
		}
	}
}

E um exemplo que lança ClassCastException (no caso aqui, como estou usando Generics, funciona equivalente a nao usar generics e o metodo compareTo receber um Object e a primeira linha do metodo eh um cast para A ou B):

public class Test {

import java.util.TreeSet;

	public static void main(String[] args) {
		TreeSet treeSet = new TreeSet();
		treeSet.add(new A());
                //quando vou colocar o segundo elemento, ele chama o compareTo do A passando um B e tenta fazer o cast para A.. nesse momento eh lancado ClassCastException.
		treeSet.add(new B());
		System.out.println(treeSet);
	}
	
	static class A implements Comparable<A> {
		public int compareTo(A o) {
                        //Se n fosse generic, eh o mesmo que receber Object e fazer A obj = (A)o;
			return 1;
		}
	}
	
	static class B implements Comparable<B> {
		public int compareTo(B o) {
			//Se n fosse generic, eh o mesmo que receber Object e fazer B obj = (B)o;
                        return 1;
		}
	}
}