Vídeos novos: segunda, quarta e sexta · 8h

Como calcular fatorial em Java: 3 exemplos práticos

Com laço, com recursão e com streams — e quando escolher cada abordagem.

O fatorial de um número inteiro n (escrito n!) é o produto de todos os inteiros de 1 até n. Por definição, 0! = 1. Exemplo: 5! = 5 × 4 × 3 × 2 × 1 = 120.

É um exercício clássico porque permite praticar três formas diferentes de pensar um problema. Vamos a elas.

1. Com laço for

A forma mais direta: começamos com 1 e multiplicamos acumulando o resultado.

public static long fatorialIterativo(int n) { if (n < 0) throw new IllegalArgumentException("n não pode ser negativo"); long resultado = 1; for (int i = 2; i <= n; i++) { resultado *= i; } return resultado; }

É rápida, não consome memória extra e é a escolha certa para produção.

2. Com recursão

A definição matemática é recursiva: n! = n × (n − 1)!. O código fica quase igual à fórmula:

public static long fatorialRecursivo(int n) { if (n < 0) throw new IllegalArgumentException("n não pode ser negativo"); if (n <= 1) return 1; // caso base return n * fatorialRecursivo(n - 1); // passo recursivo }

Elegante e ótima para aprender recursão. O cuidado: cada chamada ocupa espaço na pilha. Para o fatorial isso não é problema (o long estoura muito antes da pilha), mas em outros algoritmos recursivos profundos pode gerar StackOverflowError.

3. Com Streams

Com a API de Streams, o fatorial vira “gere os números de 1 a n e multiplique todos”:

public static long fatorialStream(int n) { if (n < 0) throw new IllegalArgumentException("n não pode ser negativo"); return LongStream.rangeClosed(1, n) .reduce(1, (a, b) -> a * b); }

Uma linha declarativa, que comunica bem a intenção. Se você ainda não domina lambdas, veja o artigo Expressões Lambda em Java.

Atenção aos limites

O fatorial cresce muito rápido. Os tipos primitivos chegam ao limite cedo:

TipoMaior fatorial que cabe
int12! = 479.001.600
long20! = 2.432.902.008.176.640.000

Passou disso, o resultado estoura silenciosamente e você recebe um número errado, sem erro nenhum. Para valores maiores, use BigInteger:

public static BigInteger fatorialGrande(int n) { BigInteger resultado = BigInteger.ONE; for (int i = 2; i <= n; i++) { resultado = resultado.multiply(BigInteger.valueOf(i)); } return resultado; } System.out.println(fatorialGrande(30)); // 265252859812191058636308480000000

Qual escolher?

  • Laço: o padrão no dia a dia — simples e eficiente.
  • Recursão: para estudar e para problemas naturalmente recursivos.
  • Streams: quando a leitura declarativa combina com o resto do código.
  • BigInteger: sempre que n puder passar de 20.