[Resolvido] como medir o nível de maturidade de um desenvolvedor java

68 respostas
G

Prezados, boa noite!

estava num processo seletivo essa semana e o rapaz que estava analisando meu código questionou que meu nível de maturidade com java era baixo ainda e ele falou isso avaliando aspectos como tratamento de exceção e conhecimento de recursos da linguagem… bem o que me deixou intrigado foi a parte do meu for no algorítimo de ordenação, vejam:

era mais ou menos assim

for(int contPrincipal = 0; contPrincipal < arrayNum.size(); contPrincipal++){ //e aqui dentro outro for similar a esse como conteudo um if e fazia a ordenação. }

bem, o cara argumentou que esse for já não é mais utilizado por desenvolvedores java faz tempo… que minha maneira de programar estava ultrapassada…
Não estou duvidando do avaliador, apenas gostaria de saber quais tipos de for em java são utilizados atualmente?
questionei ele se deveria ter usado forEach, mas não era esse o caso…
deveria mesmo é ter perguntado que tipo de for ele conhece que é utilizado pelos bons profissionais java, mas me esqueci.

68 Respostas

G

Claro, o melhor mesmo a se usar é o foreach, que é mais rápido no processamento, a sintaxe dele é assim:

String[] mensagens = {"mensagem 1","mensagem 2","mensagem 3","mensagem 4","mensagem 5"}; 
for(String msg : mensagens)
{
   System.out.println(msg);
}

vai aparecer assim:

mensagem 1
mensagem 2
mensagem 3
mensagem 4
mensagem 5

sem a utilização de um contador, e o código fica muito mais limpo, e “bonito” de se ler

A

talvez imaturidade nao seja a palavra certa. mas acho que ele disse que o modo no qual você iterou estava ultrapassado, mas nao achei nisso nenhum ‘pecado’… nada que pudesse fazer voce perder a vaga… mas acho que nesse tipo de entrevista voce tem meio que ‘surpreender’, como por exemplo, usando os recursos mais novos possiveis, comentando sobre as novidade que estarao disponiveis nas proximas versoes da linguagem e por ai vai…

L

Concordo, mas o cara também deveria ver que independe da forma como ele códificou o programa,o resultado foi o mesmo.

F

Segue a minha opinião sobre o assunto:
O novo for estabelecido na versão 5 (tiger) na verdade é um atalho (economia de sintaxe) usado para se iterar em uma coleção sem a necessidade de controlar o índice, alem de acessar o objeto da iteração. Diante disso, não é correto afirmar que o “for antigo esta ultrapassado”. Realmente não procede! Este avaliador não foi feliz na afirmação.
Maturidade em Java não se mede apenas pelo domínio de uma linguagem, uma vez q temos muitas opções diferentes hoje na JVM. Maturidade em Java é um assunto bem complexo…Para mim foi algo bem equivocado o acontecido kkkkkk

J

Esse cara que te entrevistou mostrou que ele mesmo não tem maturidade como desenvolvedor java.

Maturidade em java se defini pela qualidade do código, utilizando padrões de projeto, refactoring
e experiência em projetos.

Realmente o entrevistador que te entrevistou foi um júnior que acha que é um senior.

B

gambazinho:
Prezados, boa noite!

for(int contPrincipal = 0; contPrincipal < arrayNum.size(); contPrincipal++){ //e aqui dentro outro for similar a esse como conteudo um if e fazia a ordenação. }

Amigo,

Não sei o resto do código que vc fez, mas não há nada de errado com este for.
Apenas melhoraria da sequinte maneira.

for(int contPrincipal = 0, tam = arrayNum.size(); contPrincipal < tam; ++contPrincipal){
  //Considerando que o tamanho do array não varia
}

Quanto a avaliação, talvez o teste esperasse que vc utilizasse métodos prontos para ordenar. Collections.sort

R

Concordo, mas o cara também deveria ver que independe da forma como ele códificou o programa,o resultado foi o mesmo.

Se é por isso então vou programar tudo só em JSP,já que o resultado é o mesmo. :wink:

T

Concordo, mas o cara também deveria ver que independe da forma como ele códificou o programa,o resultado foi o mesmo.

Cuidado com essa linha de raciocínio.
Como diria Bob Martin “Até mesmo código muito ruim pode funcionar”.

Não estou dizendo que o código é ruim, mas usar foreach é uma opção muito superior.
Superior por que ele conta que quem será iterado implemente Iterable, usando então o famoso padrão Iterator.
Com isso ele encapsula a forma de iteração da coleção, ou seja, cada coleção pode possuir uma implementação específica o que garante que será iterada sempre da melhor maneira, sem que você precise se preocupar se é uma lista ligada, um array, etc…

W

johnny quest:
Esse cara que te entrevistou mostrou que ele mesmo não tem maturidade como desenvolvedor java.

Maturidade em java se defini pela qualidade do código, utilizando padrões de projeto, refactoring
e experiência em projetos.

Realmente o entrevistador que te entrevistou foi um júnior que acha que é um senior.

[2]

Na área de TI, ta cheio de gente assim, o jeito é ter paciência :?

A

Estou estranhando ser ultrapassado também. Alguém poderia esclarecer isso?

Pensei assim: e se você precisa do índice dentro do for? Vai usar indexOf todas as vezes, sendo que o indexOf tem complexidade O(n)?

public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i] == null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }

O for, dependendo da forma como é usado, pode ser otimizado. Mas, na minha concepção e entendimento de Java e performance, o for que você usou não é ultrapassado, só dificulta um pouco a leitura quando comparado com o for each.

M

axo q nao tem nada haver esse negocio do for…
eu uso um dois dependendo do que eu quero!!
se não eh interessande saber qual o index da iteracao estah sendo executado entao uso

for(String s : arrayString)

caso contrario uso

for(int i = 0; i < arrayString.length; i++)

pronto

jah que esse ‘bunitao’ disse q a moda agora eh usar o 1º tipo de for que eu citei, entao se for preciso saber qual iteracao executada no momento vai ser preciso fazer um acumulador besta soh pra isso, assim

int cont = 0;
for(String s : arrayString){
//operacao
cont++;//<== isso pra mim eh bobagem sendo que se pode poupar codigo
}

nao liga pra que ele disse

R

Bem… eu por exemplo… quase sempre quando faço um for… uso a seguinte construção:

for(int i= 0; i< arrayNum.size(); i++){

Uso a variável i

Nomes de variáveis abreviadas como cont… e num não são muito utilizadas em Java também não… se você for tirar uma certificação, você inclusive perde pontos por isso.

Mas em questão da ordenação. NUNCA faço um for dentro do outro… uso as APIs de Java para isso…

Você estava desenvolvendo utilizando alguma IDE? Qual?

R

O foreach não é mais rápido do que outro for

T

O foreach não é mais rápido do que outro for

Poderia explicar por que?

R

O foreach não é mais rápido do que outro for

Poderia explicar por que?

Quando o programa Java é compilado… o foreach é traduzido para uma construção que usa o for normal… então… o foreach é só um sintax sugar para você não ter que escrever um bocado a mais de código para fazer a mesma coisa.

No caso do foreach sobre uma coleção… ele será traduzido para um for utilizando um iterator por exemplo.

T

O foreach não é mais rápido do que outro for

Poderia explicar por que?

Quando o programa Java é compilado… o foreach é traduzido para uma construção que usa o for normal… então… o foreach é só um sintax sugar para você não ter que escrever um bocado a mais de código para fazer a mesma coisa.

No caso do foreach sobre uma coleção… ele será traduzido para um for utilizando um iterator por exemplo.

E por que o for “normal” seria mais rápido que o foreach?

R

Não falei que o for normal é mais rápido que o foreach…

T

Uai, você disser que o foreach não é mais rápido que o for “normal”.

Anyway, o foreach faz com que a iteração use um iterator.

Vejamos por exemplo, se você utilizar o for “normal” em uma implementação de lista ligada, assim você terá um desempenho muito inferior a um foreach.
Por isso que é bem melhor usar sempre iterators (explicitamente ou implícitos com foreach), por que você delega ao iterator a responsabilidade de saber a forma mais performática de… iteração, pasmem.

R

Problema de lógica…

Se A é menor que B.

Podemos afirmar que B é maior que A?

T

rogelgarcia:
Problema de lógica…

Se A é menor que B.

Podemos afirmar que B é maior que A?

Nesse caso, sim.
Não se trata de uma falácia clássica.

R

Oops… escrevi errado minha pergunta…

Se A não é maior que B.

Podemos afirmar que B é maior que A?


Mapeando para o problema atual.

Se o FOREACH nao é mais rápido que o FOR.

Podemos afirmar que o FOR é mais rápido que o FOREACH?

T

rogelgarcia:
Oops… escrevi errado minha pergunta…

Se A não é maior que B.

Podemos afirmar que B é maior que A?


Mapeando para o problema atual.

Se o FOREACH nao é mais rápido que o FOR.

Podemos afirmar que o FOR é mais rápido que o FOREACH?

Ainda a resposta é sim rsrs

Mas convenhamos, basta nos ater a resposta que fiz sobre iterators.

R

Se A não é maior que B.

Podemos afirmar que B é maior que A?

A = 5 e B = 5

A questão da performance que você mencionou… é relativa a utilizar o iterator e não ao for em si. Mesmo porque, para a máquina virtual só existe 1 for.

Curiosidade: É possível que para o caso do ArrayList… um loop sem usar o iterator pode ser (nao fiz o teste) mais rápido do que usando o iterator. O iterator faz a checagem de acesso concorrente que um loop com acesso direto ao método get(index) não faz.

R

Não, se ao utilizar o for normal… utilize a iteração do Iterator. Nesse caso é igual usar for ou foreach.

T

rogelgarcia:

A questão da performance que você mencionou… é relativa a utilizar o iterator e não ao for em si. Mesmo porque, para a máquina virtual só existe 1 for.

Curiosidade: É possível que para o caso do ArrayList… um loop sem usar o iterator pode ser (nao fiz o teste) mais rápido do que usando o iterator. O iterator faz a checagem de acesso concorrente que um loop com acesso direto ao método get(index) não faz.

Para o ArrayList pode ser, mas se você seguiu as boas práticas e programou orientado a interfaces o que te garante que você terá essa implementação? Ao mesmo modo que pode ser uma LinkedList, dai a iteração com get() usando um index seria desastroso em questão de performance.
Fora que é uma prática não recomendada iterar por indexes por ser suscetível a falhas de IndexOutOfBounds, etc…
Acredite, já ví sistemas em produção de empresas de grande porte terem problemas por conta de IndexOutOfBounds, NullPointerException e mais uma infinidade de erros banais.

Resumindo: só há vantagens em assumir uma iteração por Iterators (com ou sem foreach), seja pela segurança ou pela performance.

R

Ok então. Chegamos a conclusão que o foreach não é mais rápido que o for.

Entramos na discussão sobre usar ou não Iterators. Concordo que se deva utilizar Iterators. Não falei o contrário. :smiley:

T

Não foi isso que eu disse.
Se você prestar atenção notará que em determinadas situações foreach é mais rápido ou não.
E mesmo nos casos onde ele é menos performático essa diferença é irrelevante.
Basta colocar na balança as vantagens e desvantagens.

R

Se o foreach vira um for depois de compilado… como se pode afirmar que o foreach é mais rápido? Se são a mesma coisa…

J

Acredito que após a geração do bytecode, se houver alguma diferença de performance, esta eh irrelevante.

Na maioria dos casos a grande vantagem eh na facilidade de codificação.

T

Simples, eles não são a mesma coisa.
De novo vou usar o exemplo da lista ligada, como você iria iterar nela performaticamente através de um index?

A

Acho que a questão saiu um pouco do foco principal. Pra discutir a performance, temos vários artigos por aí (e posts em foruns maiores, tipo o StackOverflow).

Li no Effective Java a uns tempos atrás que for each é um pouco mais rápido que o for ‘genérico’, se o desenvolvedor sempre pedir o tamanho do array (ie, não souber fazer o for de uma maneira otimizada). Por exemplo:

for (int i = 0; i < list.size(); i++) {}

Possivelmente será mais lento que o

for (Object o: list) {}

Mas seria igualmente (ou muito próximo) rápido ao

for (int i = 0, size = list.size(); i < size; i++) {}

Já se usar Iterator é outra história: fica tudo mais lento.

R

Simples, eles não são a mesma coisa.
De novo vou usar o exemplo da lista ligada, como você iria iterar nela performaticamente através de um index?

for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
			String string =  iterator.next();

Quem é que falou que tem que usar o for através de um index?

T

Simples, eles não são a mesma coisa.
De novo vou usar o exemplo da lista ligada, como você iria iterar nela performaticamente através de um index?

for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
			String string =  iterator.next();

Quem é que falou que tem que usar o for através de um index?

Ai que ta a questão, um foreach usa implicitamente iterators.
Sempre.

R

Tá… e por um acaso… o código com foreach é mais rápido do que o que eu postei?

É o que eu tinha falado… não é o for ou foreach que é mais rápido… e sim, usar ou nao o iterator… duas discussões diferentes.

T

rogelgarcia:
Tá… e por um acaso… o código com foreach é mais rápido do que o que eu postei?

É o que eu tinha falado… não é o for ou foreach que é mais rápido… e sim, usar ou nao o iterator… duas discussões diferentes.

Usar foreach ou iterators explicitamente da na mesma.

R

Tchello:
rogelgarcia:
Tá… e por um acaso… o código com foreach é mais rápido do que o que eu postei?

É o que eu tinha falado… não é o for ou foreach que é mais rápido… e sim, usar ou nao o iterator… duas discussões diferentes.

Usar foreach ou iterators explicitamente da na mesma.

Aleluia irmão. Então o foreach não é mais rápido.

:wink:

T

rogelgarcia:
Tchello:
rogelgarcia:
Tá… e por um acaso… o código com foreach é mais rápido do que o que eu postei?

É o que eu tinha falado… não é o for ou foreach que é mais rápido… e sim, usar ou nao o iterator… duas discussões diferentes.

Usar foreach ou iterators explicitamente da na mesma.

Aleluia irmão. Então o foreach não é mais rápido.

;)

Errado de novo.
Usar iterators não é necessariamente mais lento que index. Já expliquei por que.

R

Você disse: Usar foreach ou iterators explicitamente da na mesma.

Isso implica em: O foreach não é mais rápido, visto que um for utilizando iterators “dá na mesma”

R

Denovo… onde é que eu falei isso? (que iterator é necessariamente mais lento que index)

T

Meu, desisto.
Você se contradiz a cada post e distorce as minhas declarações.
Abdico de comentar nesse post, fica a cargo de cada um que ler esse post interpretar da maneira que quiser.

Abraços.

R

Tchello:
Meu, desisto.
Você se contradiz a cada post e distorce as minhas declarações.
Abdico de comentar nesse post, fica a cargo de cada um que ler esse post interpretar da maneira que quiser.

Abraços.

É… sou eu quem me contradigo mesmo…

O problema é que você não entendeu a lógica. E não mostra, como eu faço com voce, onde eu estou errado.

Se A não é maior que B. [color=red][size=30]NÃO [/size][/color]se pode dizer que B é maior que A. E você acha que pode, e acha que inclusive eu disse isso.

FOREACH não é mais rápido que FOR. E FOR não é mais rápido que FOREACH.

R

Esse código..

import java.util.Iterator;
import java.util.List;


public class TesteFor {

	public static void main(String[] args) {
		List<String> lista = null;
		for (String string : lista) {
			System.out.println(string);
		}
		for (Iterator iterator = lista.iterator(); iterator.hasNext();) {
			String string = (String) iterator.next();
			System.out.println(string);
		}
	}
}
Em byte code:
0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 5]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: TesteFor
  
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 2, Locals: 4
  public static void main(java.lang.String[] args);
     0  aconst_null
     1  astore_1 [lista]

     2  aload_1 [lista]                                                                      //aqui começa o primeiro for (o foreach)
     3  invokeinterface java.util.List.iterator() : java.util.Iterator [16] [nargs: 1]       //chama o iterator
     8  astore_3                                                                             //guarda o iterator implicito
     9  goto 29                                                                              //verifica se tem próximo
    12  aload_3                                                                              //carrega o iterator
    13  invokeinterface java.util.Iterator.next() : java.lang.Object [22] [nargs: 1]         //chama o next
    18  checkcast java.lang.String [28]                                                      //faz o cast
    21  astore_2 [string]                                                                    //guarda a string
    22  getstatic java.lang.System.out : java.io.PrintStream [30]                            //pega o atributo System.out
    25  aload_2 [string]                                                                     //carrega a string
    26  invokevirtual java.io.PrintStream.println(java.lang.String) : void [36]              //chama o println
    29  aload_3                                                                              //carrega o iterator implicito
    30  invokeinterface java.util.Iterator.hasNext() : boolean [42] [nargs: 1]               //ve se tem proximo
    35  ifne 12                                                                              // se tem.. volta para o passo 12 (inicio do loop)

    38  aload_1 [lista]                                                                      //aqui começa o segundo for
    39  invokeinterface java.util.List.iterator() : java.util.Iterator [16] [nargs: 1]       //chama o iterator
    44  astore_2 [iterator]                                                                  //guarda o iterator explicito
    45  goto 65                                                                              //verifica se tem próximo
    48  aload_2 [iterator]                                                                   //carrega o iterator
    49  invokeinterface java.util.Iterator.next() : java.lang.Object [22] [nargs: 1]         //chama o next
    54  checkcast java.lang.String [28]                                                      //faz o cast
    57  astore_3 [string]                                                                    //guarda a string
    58  getstatic java.lang.System.out : java.io.PrintStream [30]                            //pega o atributo System.out
    61  aload_3 [string]                                                                     //carrega a string
    62  invokevirtual java.io.PrintStream.println(java.lang.String) : void [36]              //chama o println
    65  aload_2 [iterator]                                                                   //carrega o iterator explicito
    66  invokeinterface java.util.Iterator.hasNext() : boolean [42] [nargs: 1]               //ve se tem proximo
    71  ifne 48                                                                              //se tem ... volta para o passo 48 (inicio do loop)

    74  return
      Line numbers:
        [pc: 0, line: 8]
        [pc: 2, line: 9]
        [pc: 22, line: 10]
        [pc: 29, line: 9]
        [pc: 38, line: 12]
        [pc: 48, line: 13]
        [pc: 58, line: 14]
        [pc: 65, line: 12]
        [pc: 74, line: 16]
      Local variable table:
        [pc: 0, pc: 75] local: args index: 0 type: java.lang.String[]
        [pc: 2, pc: 75] local: lista index: 1 type: java.util.List
        [pc: 22, pc: 29] local: string index: 2 type: java.lang.String
        [pc: 45, pc: 74] local: iterator index: 2 type: java.util.Iterator
        [pc: 58, pc: 65] local: string index: 3 type: java.lang.String
      Local variable type table:
        [pc: 2, pc: 75] local: lista index: 1 type: java.util.List<java.lang.String>
      Stack map table: number of frames 4
        [pc: 12, full, stack: {}, locals: {java.lang.String[], java.util.List, _, java.util.Iterator}]
        [pc: 29, same]
        [pc: 48, full, stack: {}, locals: {java.lang.String[], java.util.List, java.util.Iterator}]
        [pc: 65, same]
}

Veja que os dois códigos são [color=blue][size=18]IGUAIS [/size][/color] portanto um não pode ser mais rápido que o outro.

T

Eu sempre disse que o foreach é idèntico a um usando iterator explicitamente. A diferença é que o foreach esconde o iterator, mas o usa de qualquer maneira.
Tente debugar um foreach que você verá um iterator escondido.
O que estou dizendo é que usar foreach não é igual a usar um for com index, compreende?

Mas de qualquer maneira, usar um foreach e/ou iterators (o que dá na mesma) é muito mais aconselhável a se usar index para percorrer a coleção.

R

Tchello:
Eu sempre disse que o foreach é idèntico a um usando iterator explicitamente. A diferença é que o foreach esconde o iterator, mas o usa de qualquer maneira.
Tente debugar um foreach que você verá um iterator escondido.
O que estou dizendo é que usar foreach não é igual a usar um for com index, compreende?

Mas de qualquer maneira, usar um foreach e/ou iterators (o que dá na mesma) é muito mais aconselhável a se usar index para percorrer a coleção.

Cara eu sei que voce sabe das coisas… pq eu já vi outros posts seu aqui.

Mas como vc mesmo disse na mensagem, a questão é usar iterator ou percorrer com index. Não é por causa do for que é mais rápido. (porque não é mais rápido… sao o mesmo for)

Em nenhum momento eu disse que percorrer index é melhor. O que eu disse é que o FOREACH não é mais rápido que o FOR, porque na verdade eles são o mesmo.
Em questão do FOR e do FOREACH apenas, não existe diferença.

L

Ao autor do post: por favor, não me leve a mal com o que vou dizer agora.
Trata-se de opinião pessoal, e de forma alguma te desqualifica. Sequer o conheço, não estou aqui pra julgar.

Muitas coisas são avaliadas com relação ao código. Uma delas, com certeza, é a legibilidade do mesmo.
Além disso, o aprendizado contínuo do desenvolvedor também se mostra no código que ele escreve.

Essa tua construção do for é a “clássica” ensinada em aula. Acho eu que o teu avaliador viu nela não um código “ruim”, mas sim:

  • que você poderia ter avaliado melhor qual construção do for utilizar, ou seja, mostrado melhor pensamento analítico;
  • ter acompanhado as mudanças / evoluções da linguagem com o tempo de melhor forma, se mantendo mais atualizado;
  • que talvez você não tenha a experiência suficiente para o cargo almejado

Me colocando no lugar do avaliador:
Eu não sei a que cargo você está / estava concorrendo, mas para uma vaga de estágio, eu não daria tanta relevância; porém, para um cargo efetivo, principalmente se não é teu primeiro emprego, eu também consideraria isso um ponto fortíssimo para tua desqualificação.

E mais: ele te deu um feedback da entrevista; só isso já prova que ele não é um babaca de marca maior. Pode até ter sido infeliz com as palavras, mas pelo menos ele te explicou exatamente o porquê da recusa à tua contratação. Agora cabe a ti aproveitar esse feedback e, quem sabe, melhorar nisso.

Desculpa se te ofendi de alguma forma. Te peço, novamente, que não me leve a mal, porquê o que estou falando é pra ajudar.

Abraço!

G

gambazinho:
Prezados, boa noite!

estava num processo seletivo essa semana e o rapaz que estava analisando meu código questionou que meu nível de maturidade com java era baixo ainda e ele falou isso avaliando aspectos como tratamento de exceção e conhecimento de recursos da linguagem… bem o que me deixou intrigado foi a parte do meu for no algorítimo de ordenação, vejam:

era mais ou menos assim

for(int contPrincipal = 0; contPrincipal < arrayNum.size(); contPrincipal++){ //e aqui dentro outro for similar a esse como conteudo um if e fazia a ordenação. }

bem, o cara argumentou que esse for já não é mais utilizado por desenvolvedores java faz tempo… que minha maneira de programar estava ultrapassada…
Não estou duvidando do avaliador, apenas gostaria de saber quais tipos de for em java são utilizados atualmente?
questionei ele se deveria ter usado forEach, mas não era esse o caso…
deveria mesmo é ter perguntado que tipo de for ele conhece que é utilizado pelos bons profissionais java, mas me esqueci.

Não se abale com isso, é possível que o motivo tenha sído outro, perfil, por exemplo, e o entrevistador quiz justificar o injustificável.

Existem muitas empresas com funcionários despreparados em seus RH’s. Eu estou no último ano de Bacharelado pela FATEC e fui descriminado por pessoas que fazem UNIBAN (com todo respeito), sendo que a ofensa não partiu da minha pessoa. Bem, eu tenho consciência, infelizmente, de que existe uma linha não muito tênue entre as instituições de ensino e não vou me martirizar por isso, acredito que os demais devam partir do mesmo princípio.

Conclusão, é muito desagradável passar por esse tipo de assédio, realmente desestabiliza.

[EDIT]Não tem nada de errado com o seu for, se eu lhe contrar as coisas que eu vejo na empresa que sou empregado… [\EDIT]

[]'s

M

eu acho realmente ridiculo avaliar alguém pela versão do for que ela escolheu... a menos é claro que vocÊ faça malabarismos dentro dos parenteses do for classico mas ai é por legibilidade do código feito, não pela versão do for...

sobre qual é mais rápido, me veio uma surpresa... aparentemente usando um arraylist o for antigo é um pouquinho mais rápido (coisa de poucos milisegundos), normalmente o povo usa arraylist... nem sempre usam um hashset por exemplo... usando um LinkedList o for antigo me foi consideravelmente mais lento...

bom, o teste é esse:

package testes.exibir;

import java.util.*;

public class TestePerformanceLoop {

	private int tamanhoLista = 100000;
//	List&lt;String&gt; lista = new LinkedList&lt;String&gt;();
	List&lt;String&gt; lista = new ArrayList&lt;String&gt;(tamanhoLista);
	
	public static void main(String[] args) {
		
		TestePerformanceLoop teste = new TestePerformanceLoop();
		System.out.println("\npreenchendo lista");
		teste.preencheLista();

		System.out.println("\ntestando iterator primeiro");
		teste.testarIterator();
		
		System.out.println("\ntestando for classico");
		teste.testarForClassico();
		
		System.out.println("\ntestando for earch");
		teste.testarForEarch();
		
		System.out.println("\ntestando ordenação:");
		teste.imprimeTempoSort();
		
	}

	public void imprimeTempoSort(){
		
		long primeiro = 0L;
		long segundo = 0L;
		long terceiro = 0L;
		Comparator c = Collections.reverseOrder();

		primeiro = System.currentTimeMillis();
		Collections.sort(this.lista);
		segundo = System.currentTimeMillis();
		Collections.sort(this.lista, c);
		terceiro = System.currentTimeMillis();

		System.out.println("tempo sort normal:"+(segundo-primeiro));
		System.out.println("tempo sort revers:"+(terceiro-segundo));
		
	}
	
	public void preencheLista(){
		for(int i=0; i&lt;tamanhoLista; i++){
			lista.add(String.valueOf(i));
		}
	}
	
	public void testarForEarch(){
		
		long primeiro = 0L;
		long segundo = 0L;
		String temp = null;
				
		primeiro = System.currentTimeMillis();
		for(String s: lista){
			temp = s;//não quero contar o IO de exibir num sysout
		}
		segundo = System.currentTimeMillis();

		System.out.println("tempo for earch:"+(segundo-primeiro));
		
	}
	
	public void testarForClassico(){

		long primeiro = 0L;
		long segundo = 0L;
		String temp = null;
		
		primeiro = System.currentTimeMillis();
		for(int i=0; i&gt;&lt;tamanhoLista; i++){
			temp = lista.get(i);//não quero contar o IO de exibir num sysout
		}
		segundo = System.currentTimeMillis();

		System.out.println("tempo for classico:"+(segundo-primeiro));
		
	}
	
	public void testarIterator(){

		long primeiro = 0L;
		long segundo = 0L;
		String temp = null;
		
		primeiro = System.currentTimeMillis();
		Iterator&gt;&lt;String&gt; it = lista.iterator();
		while(it.hasNext()){
			String s = it.next();
			temp = s;//não quero contar o IO de exibir num sysout
		}
		segundo = System.currentTimeMillis();

		System.out.println("tempo iterator:"+(segundo-primeiro));
		
	}
	
}
M

a pouco mais de um mês estava procurando um novo emprego e me lembro de algumas das perguntas de provas que fiz…

um exemplo de uma pergunta bem elaborada colocou uma situação onde temos um arquivo local e devemos comparar ele com outros arquivos na rede gastando o minimo possível de recursos de rede que neste caso seriam escassos… e perguntava como faríamos isso, mesmo sem precisar codificar, apenas explicar como fariamos… eu achei esta uma pergunta boa para ver “maturidade” do programador…

cheguei a encontrar algumas outras perguntas bem pertinentes, esta é só um exemplo (apesar de a maioria ainda serem perguntas de scjp mesmo…).

G

O foreach não é mais rápido do que outro for

Poderia explicar por que?

hehe, o cara afirma, mas não argumenta a opinião.

L

bem na verdade o cara que estava equivocado… pois para fazer um bubblesort da vida vc vai precisar de um for que contenha indices a menos que use um foreach e fique incrementando um int (que ao meu ver é estupido…), mas provavelmente ele esperava que vc não usasse nenhum for… que fizesse um quicksort apenas com recursividade… seria o modo mais elegante de resolver um problema de ordenação…

R

O foreach não é mais rápido do que outro for

Poderia explicar por que?

hehe, o cara afirma, mas não argumenta a opinião.

Não é opinião e está argumentado. É só ler os posts.

G

Se vc diz tá certo, vou sempre usar o for normal daqui em diante.

G

poderia me dar um exemplo dessa recursividade sem for? pois realmente não estou conseguindo entender isso.

L

poderia me dar um exemplo dessa recursividade sem for? pois realmente não estou conseguindo entender isso.

import java.util.Arrays;
import java.util.Random;
 
public class QuickSort {
    public static final Random RND = new Random();
 
    private static void swap(Object[] array, int i, int j) {
        Object tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
 
    private static <E extends Comparable<? super E>> int partition(E[] array, int begin, int end) {
        int index = begin + RND.nextInt(end - begin + 1);
        E pivot = array[index];
        swap(array, index, end);
        for (int i = index = begin; i < end; ++i) {
            if (array[i].compareTo(pivot) <= 0) {
                swap(array, index++, i);
            }
        }
        swap(array, index, end);
        return (index);
    }
 
    private static <E extends Comparable<? super E>> void qsort(E[] array, int begin, int end) {
        if (end > begin) {
            int index = partition(array, begin, end);
            qsort(array, begin, index - 1);
            qsort(array, index + 1, end);
        }
    }
 
    public static <E extends Comparable<? super E>> void sort(E[] array) {
        qsort(array, 0, array.length - 1);
    }
 
    // Exemplo de uso
    public static void main(String[] args) {
 
        // Ordenando Inteiros
        Integer[] l1 = { 5, 1024, 1, 88, 0, 1024 };
        System.out.println("l1  start:" + Arrays.toString(l1));
        QuickSort.sort(l1);
        System.out.println("l1 sorted:" + Arrays.toString(l1));
 
        // Ordenando Strings
        String[] l2 = { "gamma", "beta", "alpha", "zoolander" };
        System.out.println("l2  start:" + Arrays.toString(l2));
        QuickSort.sort(l2);
        System.out.println("l2 sorted:" + Arrays.toString(l2));
    }
}

na verdade ele usa um for mas isto não é o ponto chave na implementação…

fonte: http://pt.wikipedia.org/wiki/Quicksort

R

Uma observação: Deve-se tomar cuidado com a recursividade, pois o número de iterações dependendo do problema pode ser muito alto. E com isso o gasto de memória também. As vezes uma solução não recursiva pode ser melhor recomendada, cada caso é um caso.

V

Quem quer saber se o código é imaturo ou não, leia o Effective Java. Se você se surpreender com que é dito lá, então seu código é imaturo.

Se você ainda não sabe o que é “programar para interfaces” ou “liberar recursos”, seu código é imaturo.

Se você só tem idéia do que sejam design patterns, mas só usou um ou outro na prática, então seu código é imaturo.

Se você não conhece a fundo as collections, não as usa através de suas interfaces, e não tem a menor noção da diferença de performance e espaço de memória ocupada por elas, então, seu código é imaturo.

E procure sempre usar as construções novas da linguagem. Elas não estão lá à toa. Por exemplo, a questão de percorrer uma lista com o for each é bastante relevante. Um LinkedList percorrido pelo índice tem uma performance péssima. Tão péssima que chega a ser ridículo sequer considerar essa opção para qualquer código sério.

Evidentemente seu avaliador citou o uso do for como um exemplo. Agora, eu estaria mais atento ao que ele falou das exceções. Provavelmente ali você deu um indício claro de que não sabe a utilidade do finally, ou não sabe propagar exceptions corretamente, um forte sinal de código imaturo.

T

ViniGodoy:
Quem quer saber se o código é imaturo ou não, leia o Effective Java. Se você se surpreender com que é dito lá, então seu código é imaturo.

Se você ainda não sabe o que é “programar para interfaces” ou “liberar recursos”, seu código é imaturo.

Se você só tem idéia do que sejam design patterns, mas só usou um ou outro na prática, então seu código é imaturo.

E procure sempre usar as construções novas da linguagem. Elas não estão lá à toa. Por exemplo, a questão de percorrer uma lista com o for each é bastante relevante. Um LinkedList percorrido pelo índice tem uma performance péssima. Tão péssima que chega a ser ridículo sequer considerar essa opção para qualquer código sério.

Assinado.
Era exatamente o que eu vinha dizendo…
Por isso é sempre mais seguro e provavelmente mais rápido percorrer com foreach, pq se você programou orientado a interfaces quem te garante que aquela implementação de List ou mesmod e Collection é um LinkedList ou ArrayList ou QualQuerList?
Não importa qual implementação seja! Deixe o iterator se preocupar com isso, as interfaces servem pra isso, respeitam o contrato !!

V

Vou mostrar aqui o que o esse código inocente:

Fazer isso num LinkedList:

for (int i = 0; i &lt; list.size(); i++) { int valor = list.get(i); }

É mais ou menos equivalente a fazer isso num ArrayList:

for (int i = 0; i &lt; list.size(); i++) int aux; for (int j = 0; j &lt; i; j++) { aux = list.get(j); } int valor = aux; }

Isso mesmo. O get da LinkedList sempre percorre do primeiro até o n-ésimo elemento. Não existem índices de fato num LinkedList. Então, se vc ainda troca o for each por um for comum só poque precisa de um índice, principalmente se estiver iterando sobre um List (que vc não sabe se é Array ou LinkedList), seu código é imaturo.

V

Esqueci de uma muito importante:

Se você não lê a documentação oficial (javadoc e tutoriais da Oracle), nem está preocupado em manter boas práticas, seu código é imaturo.

Sério pessoal, é impressionante a quantidade de gente que vejo aqui recomendando métodos que o javadoc diz para não serem usados (requestfocus de componentes, stop() de threads, etc), ou mesmo insistindo em más práticas (DefaultTableModel é meu exemplo mais clássico, mas dá para citar também ignorar exceptions ou sobrescrever o paint de componentes ao invés do paintComponent, ou concatenar Strings dentro de fors).

Tudo isso indica claramente que o sujeito não leu a documentação. Básico para qualquer um que queira usar com efetividade uma linguagem.

E documentação existe aos montes. Há os trails da Oracle, o próprio Javadoc e os artigos do Brian Goetz. Obrigatórios.

São em inglês, mas claro, se você não sabe inglês e nem quer aprender, está na área errada. Vá cursar letras, direito, filosofia… aí talvez vc possa levar uma vida sem inglês.

L

Falou tudo.
É o famoso “RTFM”. Se o cara não sabe nem pra que serve cada um dos componentes que ele usa, acaba usando do jeito errado.
“Pra quem só tem martelo, tudo é prego”.

L

É verdade tem que tomar muito cuidado… dependendo do caso ela pode ser brilhante como no uso para o quicksort ou na resolução de puzzles como torre de hanoi ou na construção de compiladores ela é essencial… mas poderá tmb ser catastrófica principalmente se usar instancias que tenham seu ciclo de vida fora do escopo do metodo recursivo (na memoria heap e não na pilha) ou se por algum motivo a condição de retorno do metodo não for atingida…

J

Recursividade é usada somente quando o limite tende ao infinito, do contrário qualquer laço pode resolver o problema.

G

ViniGodoy:
Esqueci de uma muito importante:

Se você não lê a documentação oficial (javadoc e tutoriais da Oracle), nem está preocupado em manter boas práticas, seu código é imaturo.

Sério pessoal, é impressionante a quantidade de gente que vejo aqui recomendando métodos que o javadoc diz para não serem usados (requestfocus de componentes, stop() de threads, etc), ou mesmo insistindo em más práticas (DefaultTableModel é meu exemplo mais clássico, mas dá para citar também ignorar exceptions ou sobrescrever o paint de componentes ao invés do paintComponent, ou concatenar Strings dentro de fors).

vini, se eu fizer:

String letra = "a";

for(int a=0; a &lt; 10;a++){
  letra+="b";
}

está errado? é isso o que quer dizer com concatenar string dentro de um for? qual problema dessa prática?

V

Está errado sim. O problema é que Strings são imutáveis. Nesse caso, o java irá criar e destruir objetos o tempo todo, a cada nova concatenação. Isso consome muitíssimo mais tempo do que se você usasse a classe StringBuilder.

O correto seria:
StringBuilder letra = new StringBuilder(&quot;a&quot;);

for(int a=0; a &lt; 10;a++){
  letra.append(&quot;b&quot;);
}

String frase = letra.toString();

Isso é descrito nos artigos do Brian Goetz:
http://www.ibm.com/developerworks/java/library/j-jtp02183/index.html

E no livro Effective Java. Se você quer aumentar a maturidade do seu código Java, recomendo fortemente a leitura desse livro.

G

show de bola, vivendo e aprendendo! De fato sou muito imaturo ainda e tenho muito o que aprender! essa experiência me fez perceber isso.
E a respeito do inglês é isso mesmo que o vini falou! TODO mundo me diz que sem inglês vc n chega a lugar algum. Pra mim inglês é foda, mas vou começar um curso mês que vem e ve se supero esse medo!
Um dia ainda viro sênior!!!
Obrigado a todos os que me responderam e se maios alguém tiver algo pra compartilhar sinta-se a vontade.

T
ViniGodoy:
Está errado sim. O problema é que Strings são imutáveis. Nesse caso, o java irá criar e destruir objetos o tempo todo, a cada nova concatenação. Isso consome muitíssimo mais tempo do que se você usasse a classe StringBuilder. O correto seria:
StringBuilder letra = new StringBuilder(&quot;a&quot;);

for(int a=0; a &lt; 10;a++){
  letra.append(&quot;b&quot;);
}

String frase = letra.toString();

Isso é descrito nos artigos do Brian Goetz:
http://www.ibm.com/developerworks/java/library/j-jtp02183/index.html

E no livro Effective Java. Se você quer aumentar a maturidade do seu código Java, recomendo fortemente a leitura desse livro.

Eu diria mais, Effective Java é leitura obrigatória pra todo desenvolvedor Java.
Mas não atropelem, ele é um livro para programadores mais experientes, não pra alguém que está começando na linguagem.

G

Tchello:

Eu diria mais, Effective Java é leitura obrigatória pra todo desenvolvedor Java.
Mas não atropelem, ele é um livro para programadores mais experientes, não pra alguém que está começando na linguagem.

Que livro vc recomendo pra quem está começando? estou lendo a apostila da caelum sobre OO. Acredito ser um bom começo estudar novamente a OO.

V

Se você ainda tem dúvida sobre a sintaxe básica, nesse caso, você deve primeiro pegar livros para reforça-la.

Em todo caso, montei um roadmap de livros no meu site para quem quer deixar de ser iniciante em Java. Ele aborda vários conceitos (linguagem, objetos, boas práticas, etc) e os livros estão em ordem.

Dê uma olhada: http://www.pontov.com.br/site/index.php/java/47-javageral/89-roadmap-java

Não há temas de desenvolvimento web, ou outras tecnologias específicas, só de fundamentos.

Criado 22 de junho de 2011
Ultima resposta 4 de jul. de 2011
Respostas 68
Participantes 20