Olá, Diego. Como vai?
Sua linha de raciocínio está totalmente correta e você teve uma excelente percepção sobre otimização de código.
A abordagem que você utilizou é, de fato, muito mais eficiente do que a solução tradicional que passa de um em um. Vamos entender o motivo técnico disso:
Análise de Eficiência
Na solução tradicional que utiliza uma estrutura condicional, o código precisaria rodar 101 vezes (de 0 até 100), executando uma operação de resto da divisão dentro de cada iteração, mais ou menos assim:
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
somaDosPares += i;
}
}
No seu código, ao utilizar o incremento i += 2, o laço for roda exatamente 51 vezes. Isso significa que você reduziu o número de iterações pela metade e eliminou completamente a necessidade de o processador avaliar a condição do if a cada volta do laço. Em termos de complexidade de algoritmo, ambos são lineares, mas o seu código executa metade das instruções na CPU.
Boas Práticas e Alternativas Modernas
Essa técnica de ajustar o passo do loop (o step) é uma excelente prática quando temos total controle e certeza sobre os limites e a lógica do problema.
Apenas como complemento para o seu aprendizado, caso você estivesse trabalhando com uma lista dinâmica de números onde não soubesse a ordem deles (por exemplo, uma lista de idades ou valores vindos de um banco de dados), a validação com o if ou o uso de Streams do Java 8 seria necessária.
Com as Streams do Java moderno, o seu raciocínio de filtro e soma poderia ser escrito de forma muito declarativa, embora o loop tradicional que você fez continue sendo o mais performático para esse caso específico:
import java.util.stream.IntStream;
int soma = IntStream.rangeClosed(0, 100)
.filter(i -> i % 2 == 0)
.sum();
Parabéns pela iniciativa de não apenas resolver o problema, mas pensar em como tornar o software mais rápido e inteligente. Essa mentalidade de buscar a eficiência faz toda a diferença na carreira de um desenvolvedor!
Espero que possa ter lhe ajudado!