Migrando para Java 5.0

Oi,

Estou testando um código para Java 5:

[code]public static void main(String[] args)
{
List lista;

lista.add(5);

}[/code]

De acordo com a revista, utilizando o na declaração da variavel,
não importa se o elemento adicionado é do tipo int (5)… pois ele ira fazer a conversão automatica…

Então, porque essa coisa não funciona?

Tenho duvidas a respeito do For e outras coisas tbm rsrs… se o pessoa conseguir me passar um exemplo, ficaria feliz =)

Tchauzin!

oi lina,

o q acontece ai eh que 5 eh um literal inteiro e, gracas ao autoboxing sera “trocado” por new Integer(5).

Como Integer e Double sao possuem uma relacao pai - filho, o codigo nao compila. Se vc colocar 5d, 5D ou ainda 5.0, compila perfeitamente.

Sacou??

Não funciona prq vc não esta atribuindo nada a lista, ele nem sequer esta sendo inicializada.

Em relação a seu código:

public static void main(String[] args)
{
    List<Double> lista;
        
    lista.add(5);
}

List é interface.
Você não pode add 5 em uma interface. Crie uma instãncia de classes implementadoras…

[code]
public static void main(String[] args)
{
List lista;
lista = ArrayList ();
lista.add(5);
}

Existem três classe que implementam List: ArrayList, Vector e LinkedList

Até +.

[quote=thadeurc]oi lina,

o q acontece ai eh que 5 eh um literal inteiro e, gracas ao autoboxing sera “trocado” por new Integer(5).

Como Integer e Double sao possuem uma relacao pai - filho, o codigo nao compila. Se vc colocar 5d, 5D ou ainda 5.0, compila perfeitamente.

Sacou??[/quote]

Tudo bem… a de colocar 5d ou 5D eu já sabia…
mãs, o porque do <Double> então? se não seria para fazer a conversão automatica de Integer para Double… rsrs

List<Double> lista = null; lista.add(5d);

O certo é

public static void main(String[] args)
{
&nbsp;&nbsp;&nbsp;&nbsp;List<Double> lista = new ArrayList<Double>();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;lista.add(5D);
}

Abs

Isso não vem ao caso… iniciada.

[quote=lina][quote=thadeurc]oi lina,

o q acontece ai eh que 5 eh um literal inteiro e, gracas ao autoboxing sera “trocado” por new Integer(5).

Como Integer e Double sao possuem uma relacao pai - filho, o codigo nao compila. Se vc colocar 5d, 5D ou ainda 5.0, compila perfeitamente.

Sacou??[/quote]

Tudo bem… a de colocar 5d ou 5D eu já sabia…
mãs, o porque do <Double> então? se não seria para fazer a conversão automatica de Integer para Double… rsrs

List<Double> lista = null; lista.add(5d); [/quote]

Na verdade não… o <Double> é para dizer que essa collection só irá guardar objetos do tipo Double… não é para fazer conversão automática, mas sim para evitar casts… dê uma estudada em Generics…

Hum,
dai sim…
ficara muito melhor evitando os cast.

O problema foi a revista picareta que eu comprei =)

Diz ela que alem de evitar o uso de (cast) iria fazer a conversão automatica, até espantada eu fiquei hahahaha

Tchauzin!

[code]

List lista = null;

lista.add(5d);[/code] :shock: :shock: :shock: :shock: :shock:

Sei que todo mundo já deu seu pitaco, mas vou dar o meu tbm :smiley:

lina, é o seguinte, a partir do Java 5 existe a possibilidade de se usar tipos genéricos e eles funcionam da seguinte maneira:

Java 1.4 ou anterior:

[code]
// as coleções armazenam “apenas” Objects, ou seja, qualquer tipo de instância.
List lista = new ArrayList();
lista.add( “string” );
lista.add( new Integer( 1 ) );
lista.add( new JLabel( “label” ) );

// sendo assim, para recuperar os dados vc teria que dar um cast explícito
String s = ( String ) lista.get( 0 );
Integer i = ( Integer ) lista.get( 1 );
JLabel l = ( JLabel ) lista.get( 2 );[/code]

É claro que você vai logicamente guardar instâncias da mesma classe, coloquei vários tipos só para exemplificar.

Já a partir do Java 5, com os genéricos, vc pode especificar que uma coleção (ou mesmo uma classe que você implementou) vai trabalhar com dados de uma classe específica. Se caso vc não especifique, o compilador irá gerar um warning avisando que você está realizando operações que não são seguras. Tome como exemplo o que passei acima. Vamos supor que em tempo de execução sua lista armazenou outra String na segunda posição. Se vc der o cast para Integer vai dar problema (ClassCastException). Os genéricos asseguram que uma coleção (ou uma classe sua como falei) vai guardar apenas referências de um tipo específico, não tendo problema ao tentar recuperar esses dados. O legal é que ao recuperar não há a necessidade de se realizar um cast. Vamos ao exemplo:

[code]
List< String > lista = new ArrayList< String >();
lista.add( “olá” );
lista.add( “genéricos” );

// não tem o cast!
String s1 = lista.get( 0 );
String s2 = lista.get( 1 );[/code]

Outra coisa importante a se notar é que tbm a partir do Java 5, existe o auto boxing e o auto unboxing que servem respectivamente para empacotar um primitivo em sua classe empacotadora e desempacotar um primitido de sua classe empacotadora. Olha o exemplo

Integer i = 1; Double d = .1; Character c = 'a';

Sendo assim, se vc tiver uma coleção que use como tipo um Double por exemplo, vc pode passar um literal double diretamente para a coleção

[code]
List< Double > lista = new ArrayList< Double >();
lista.add( 1d );
lista.add( 2d );
lista.add( 3.5 );

Double d1 = lista.get( 0 );
double d2 = lista.get( 1 );
double d3 = d1 + d2;[/code]

Só mais uma coisa, o cast implícito de int para Double não funciona no casso de se usar o boxing e unboxing, por exemplo

[code]
// tipos imcompatíveis
Double d1 = 1;

// ok, 2 é um double
Double d2 = 2d;

// ok, cast implícito
double d3 = 1;[/code]

Último detalhe, os genéricos e o boxing/unboxing são serviços do compilador. Ele primeiro converte o código para código “antigo” realizando os casts necessários e depois compila o código. São apenas “atalhos” de codificação.

Até mais!

Um pouco mais a frente, vc já preencheu sua lista e quer, em outra parte do código imprimir os objetos da lista, para isso vc pode utilizar o for iterado, for collection ou o for each. Não tenho certeza quanto aos nomes, mas acho que isso não importa muito… :lol:

        List<Double> lista = new ArrayList<Double>();
        //For iterado
        for (int i = 0; i &lt args.length; i++) {
            System.out.println(lista.get(i));
        }
        //for collection
        for (Iterator<Double> it = lista.iterator(); it.hasNext();) {
            System.out.println(it.next());
        }
        //for each
        for (Double elem : lista) {
            System.out.println(elem);
        }

:?: :?: :?:

O correto é:

for ( int i = 0; i &lt lista.size(); i++ ) ...

E para iterar usando um Iterator aconselho usar um while ao invés de um for, pois fica mais legível.

[code]
Iterator&lt Double &gt it = lista.iterator();

while ( it.hasNext() ) {

}[/code]

Até mais!

Acho que é mais aconselhável usar um "for" em vez de um "while" ao usar iteradores, porque eles limitam o escopo. Melhor ainda, não use o "iterador" explicitamente; use o recurso do "for".

Sujeito a erros:

Iterator&lt Double &gt it = lista.iterator();     
while ( it.hasNext() ) {
    Double d = it.next(); // viu? você estava esquecendo de usar o valor
}
// depois do while o "it" ainda está no escopo, e pode 
// ocasionar algum problema se indevidamente usado 

Sujeito a menos erros:


for (Iterator<Double> it = lista.iterator();  it.hasNext();  ) {
    Double d = it.next(); // viu? você estava esquecendo de usar o valor
} 
// depois do "for" o "it" saiu do escopo e o nome da variável pode ser reaproveitado:
for (Iterator <String> it = bla.iterator(); it.hasNext(); ) {
     String s = it.next();
}

Mais simples e menos sujeito a erros:

for (Double d : lista ) {
    // viu? Não tem iterator, nem tem de usar it.hasNext ou it.next. 
}

Oi,
Nossa… muito Obrigada mesmo pela ajuda!

ajudou muito!!

Tchauzin!