[Resolvido] Comando if aninhado no comando for

Estou com dúvida na compreensão desse programa que funciona perfeitamente. Até onde já aprendi, após ambas avaliações possíveis da expressão do if ele iria retornar true ou false para o método e terminaria a execução do método. Mas, parece que há um retorno para o for novamente e o reinicio da avaliação até alcançar o último índice do arranjo onde a avaliação do if será true e retornará ao método o false. O que faz o if não fazer uma única e definitiva seleção? Seria pelo fato de ele está aninhado dentro do for?

[code]
class exercicio4{
public static void main(String[] args){
int [] arranjo= new int[] {2,2,2,2,2,3};
//iguais(arranjo);
System.out.println(iguais(arranjo));
}

static boolean iguais(int[] ai){
if(ai==null| ai.length<=1 )return true;
for(int i=0; i<ai.length-1; i++)
  if(ai[i]!=ai[i+1]) return false; //como entender a interação?
return true;

}
}[/code]

Att,

return para é retornar de um método.
break é para parar uma estrutura de repetição
continue é para pular para a próxima iteração em uma estrutura de repetição.

O que o seu código faz é verificar se todos os elementos de um array são iguais correto?
Ele compara cada par adjacente de elementos.

Se algum par (ai[i] e ai[i+1]) forem diferentes, quer dizer que o array não tem pelo menos um par de elementos iguais (em toda sua extensão), sendo assim a execução do método é finalizada e é então retornado false. Perceba que o for não continua executando, pois o método terminou, sendo assim, vc economiza tempo. Caso todo o for tenha executado e nenhuma diferença tenha sido encontrada, o método retorna true.

O return no caso, como disse, é para terminar a execução do método, retornando um valor (ou não caso o método seja void).

Existem algumas soluções diferentes para seu algoritmo, sendo menos “performáticas”.

Por exemplo, percorrendo todo o for:

boolean diferente = false; for(int i=0; i<ai.length-1; i++) if(ai[i]!=ai[i+1]) diferente = true; return diferente;

Parando o for e continuando a execução do método até a última linha:

boolean diferente = false; for(int i=0; i<ai.length-1; i++) { if(ai[i]!=ai[i+1]) { diferente = true; break; } } return diferente;

Perceba que a solução que vc fez é mais rápida, pois ao encontrar o problema já retorna direto.

Entendeu?

[]´s

Muito obrigado pelo retorno.

Desculpa não ter informado o que o método faz, é realmente o que vc disse.

Ainda tenho a mesma dúvida, vou tentar me expressar melhor dessa vez.

   [code] class exercicio4{
public static void main(String[] args){
int [] arranjo= new int[] {2,2,2,2,2,3};
System.out.println(iguais(arranjo));
}

static boolean iguais(int[] ai){
    if(ai==null| ai.length<=1 )return true;
    for(int i=0; i<ai.length-1; i++)

[/code]

a primeira interação do for será avaliada como true, e passará para o comando if

 [code] if(ai[i]!=ai[i+1]) return false;[/code]

a avaliação do if será false, pois possuem valores iguais ambos índices (ai[i]!=ai[i+1]). Então ele retornará o return true, que está logo aqui embaixo:

[code] return true;

}
} [/code]

aqui surge a dúvida: Por que o programa não termina já na primeira avaliação do if, já que já temos um return? Não entendo por que após a primeira avaliação o for será executado novamente, uma vez alcançado o primeiro return dentro de um método o fluxo de controle não retorna para o main e finaliza o programa? Ou se trata de algum método recursivo e não me dei conta ainda?

Não não não!

Está vendo como faz falta usar as chaves? Dificulta o entendimento do código.
Vc pode ter um for e um if sem chaves, sendo assim, apenas a primeira instrução é considerada do bloco.

O return true do seu código não faz parte do for! Ele está fora do for.

Seu código é equivamente a

static boolean iguais(int[] ai){ if(ai==null | ai.length<=1 ) { return true; } for(int i=0; i<ai.length-1; i++) { if(ai[i]!=ai[i+1]) { return false; } } return true; // está vendo? o return true não está dentro do for, apenas o if. }

Sugiro que use o operador de curto circuito or ( || ) ao invés de apenas |, pois seu código usando o | pode diparar uma NullPointerException. O “|” força a avaliação dos dois lados da expressão, mesmo que a primeira retorne true. Usando ||, assim que a primeira parte for avaliada como true, o bloco do if é executado. No seu código, tente passar um null como parâmetro para o método para vc ver o que vai acontecer.

Seu código não é recursivo (recursão é quando um método chama a ele mesmo ou a outro método que chama o primeiro, etc).
Agora só apenas como curiosidade, vc consegue algo parecido usando recursão que vc mencionou. Nesse algoritmo é algo totalmente “inútil” pois a solução pode ser alcançada de forma fácil através de um algoritmo iterativo (que é o quê vc fez).

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

System.out.println( igual( new Integer[]{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }) );

}

public static boolean igual( Integer[] array ) {

if ( array.length == 1 ) {
    return true;
} else if ( array[0] != array[1] ) {
    return false;
} else {
    List<Integer> lista = Arrays.asList( array );
    /* poderia ter feito lista.remove(0) ao invés de criar uma sublista, 
     * mas a implementação de lista retornada pelo método asList de 
     * Arrays não suporta o método remove() (que é opcional pelo 
     * contrato da interface List)
     */
    return igual( lista.subList( 1, lista.size() ).toArray( new Integer[0] ) );
}

}[/code]

Use sempre chaves para delimitar seus blocos, a leitura fica mais fácil.
Mesmo quando vc fica experiente e consegue bater o olho no código e ver o quê faz parte do quê, é legal usar as chaves para alguém com menos experiencia entender tbm.

[]´s

Finalmente entendi =)

[code]static boolean iguais(int[] ai){
if(ai==null || ai.length<=1 ) {
return true;
}

for(int i=0; i<ai.length-1; i++){ //quando o if é avaliado false ele retorna novamente ao for, 
       if(ai[i]!=ai[i+1]){        //dentro do qual está aninhado, e reiinicia a iteração, e quando o for                        
        return false;             //estiver avaliado como false o fluxo vai finalmente para o return true.
     }  
 
 }  
 return true;    

}
}[/code]

Fiz o teste do operador ||, e realmente saiu um NullPointerException. Já fiz a alteração sugerida.

Muito obrigado!

De nada Luciano.

Só tome cuidado com a identação do seu código, está um pouco bagunçada. Boa identação também ajuda compreenção :wink:

[]´s