Oii, João Claudio! Como vai?
Excelente iniciativa de testar as duas abordagens! É exatamente assim, experimentando, que fixamos os conceitos. Ambas as formas funcionam corretamente para validar o CPF, mas a diferença principal está em performance e reaproveitamento.
- O que acontece "por baixo dos panos"?
Quando você usa o método cpf.matches(regex), o Java, internamente, faz exatamente o que você fez manualmente no seu código com Pattern e Matcher.
Basicamente, o método String.matches é um atalho (um "açúcar sintático") que executa isto:
return Pattern.compile(regex).matcher(this).matches();
- A questão da Performance (O seu
while)
Aqui está o "pulo do gato" para o seu exemplo específico.
String.matches: Toda vez que essa linha é lida, o Java precisa "compilar" a expressão regular novamente para entendê-la. Se isso estiver dentro de um loop (como o seu while(true)) e o usuário errar o CPF 100 vezes, o Java vai recompilar a regex 100 vezes.Pattern.compile: A vantagem dessa classe é que você pode compilar a regex uma única vez e reaproveitar a lógica pronta.
Observação importante sobre o seu código:
Notei que, no seu exemplo com Pattern, a linha Pattern.compile(...) também ficou dentro do while. Dessa forma, ele também está recompilando a cada volta, perdendo a vantagem de performance.
Para otimizar, o ideal seria declarar o Pattern fora do loop, algo assim:
// Compila UMA vez só
Pattern pattern = Pattern.compile("\\d{3}.\\d{3}.\\d{3}-\\d{2}$");
while (true) {
System.out.println("Digite o CPF: ");
String cpf = input.nextLine();
Matcher matcher = pattern.matcher(cpf); // Só cria o verificador (leve)
if (matcher.matches()) {
// ...
}
}
- Resumo: Quando usar qual?
| Método | Quando usar? | Vantagem |
|---|
String.matches(regex) | Para validações simples, únicas e rápidas (ex: validar um email num formulário simples). | Código mais limpo, curto e legível. |
**Pattern e Matcher** | Quando você vai validar muitas Strings repetidamente (loops) ou precisa de recursos avançados (como extrair partes do texto, grupos, ou buscar múltiplas ocorrências). | Alta performance e controle granular sobre a busca. |
Como é um exercício didático e o volume de dados é pequeno (apenas um usuário digitando), o String.matches é perfeitamente aceitável e deixa o código mais limpo. Mas, em um sistema real processando milhares de CPFs de um arquivo, o Pattern (instanciado fora do loop) seria a escolha correta!
Espero que isso tenha clareado a diferença. Bons estudos!
Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!