1
resposta

Dúvida sobre quando usar o Pattern/Matcher e Quando usar o matches(regex)

Gerei a solução usando Pattern e Matcher e resolveu, aí comenei e usei o String Regex e também funcionou:

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class ValidarCPF {
    public static void main(String[] args) {

        while (true) {
            Scanner input = new Scanner(System.in);

            System.out.println("Digite o CPF: ");
            String cpf = input.nextLine();

//            String regex = "\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}";
            Pattern pattern = Pattern.compile("\\d{3}.\\d{3}.\\d{3}-\\d{2}$");
            Matcher matcher = pattern.matcher(cpf);

            if (matcher.matches()) {
//            if (cpf.matches(regex)) {
                System.out.println("CPF no formato correto");
                break; //Interrompe o programa
            } else {
                System.out.println("CPF em formato Inválido. Digite novamente");
            }
        }
    }
}

Gostaria de entender melhor quando usar um e quando usar outro

1 resposta

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.

  1. 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();

  1. 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()) {
        // ...
    }
}
  1. Resumo: Quando usar qual?
MétodoQuando 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!

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!