Entrada Padrão em Java Explicada: Scanner vs BufferedReader e Técnicas de Entrada Rápida

目次

1. O que você aprenderá neste artigo (Conclusão rápida)

Existem várias maneiras de lidar com entrada padrão em Java, mas a ideia principal é simples:

Escolha o método de entrada com base no seu objetivo.

Você não precisa da solução mais rápida ou mais complexa desde o início.
Este artigo explica a entrada padrão em Java passo a passo, para que você possa entender claramente quando e por que usar cada abordagem.

Cobriremos a entrada em Java em três níveis práticos:

  • Para iniciantes e pequenos programas : Scanner
  • Para entradas maiores e desempenho estável : BufferedReader
  • Para programação competitiva e entrada muito grande : FastScanner

1.1 Qual você deve usar? (Scanner vs BufferedReader vs Entrada rápida)

Se você está com pressa, esta seção por si só já é suficiente para decidir.

1) Aprendendo Java ou lidando com pequenas entradas → Scanner

  • Casos de uso típicos: wp:list /wp:list
    • Tutoriais Java
    • Tarefas escolares
    • Pequenas ferramentas de linha de comando
  • Vantagens: wp:list /wp:list
    • Muito fácil de escrever
    • Fácil de ler e entender
  • Desvantagens: wp:list /wp:list
    • Lento quando o tamanho da entrada se torna grande

Use Scanner quando:

  • O tamanho da entrada é pequeno
  • Legibilidade é mais importante que desempenho

2) Entrada grande ou desempenho estável → BufferedReader

  • Casos de uso típicos: wp:list /wp:list
    • Aplicações práticas
    • Processamento em lote
    • Exercícios de programação com muitas linhas de entrada
  • Vantagens: wp:list /wp:list
    • Muito mais rápido que Scanner
    • Comportamento previsível e estável
  • Desvantagens: wp:list /wp:list
    • Você deve analisar manualmente números e tokens

BufferedReader é uma boa escolha quando:

  • O tamanho da entrada é grande
  • O desempenho importa
  • Você quer controle total sobre o processamento da entrada

3) Programação competitiva ou entrada massiva → FastScanner

  • Casos de uso típicos: wp:list /wp:list
    • Programação competitiva
    • Problemas com limites de tempo muito rígidos
  • Vantagens: wp:list /wp:list
    • Extremamente rápido
  • Desvantagens: wp:list /wp:list
    • Difícil de ler
    • Difícil de depurar
    • Não adequado para desenvolvimento de aplicações regulares

FastScanner é apropriado quando:

  • O tamanho da entrada é enorme
  • Scanner ou BufferedReader causam erros de limite de tempo

1.2 Para quem este artigo é destinado

Este artigo foi projetado para uma ampla gama de desenvolvedores Java.

Iniciantes

  • Quer entender o que entrada padrão significa
  • Precisa de uma explicação clara do Scanner
  • Frequentemente confuso com bugs relacionados à entrada

Aprendizes intermediários

  • Já conhece o Scanner
  • Quer entender por que ele se torna lento
  • Precisa de uma forma confiável de lidar com grandes entradas

Programadores competitivos

  • Precisa de técnicas de entrada rápidas
  • Quer modelos práticos para competições

1.3 O que você será capaz de fazer após a leitura

Ao final deste artigo, você será capaz de:

  • Entender o que realmente é a entrada padrão Java ( System.in )
  • Escolher o método de entrada correto para cada situação
  • Usar Scanner sem armadilhas comuns
  • Ler grandes entradas de forma eficiente com BufferedReader
  • Lidar com entrada de programação competitiva usando técnicas rápidas
  • Depurar problemas comuns relacionados à entrada com confiança

1.4 O que vem a seguir

Na próxima seção, explicaremos o que realmente significa “entrada padrão” em Java, começando a partir de System.in.

Entender esta base tornará as diferenças entre Scanner, BufferedReader e métodos de entrada rápida muito mais claras.

2. O que é “entrada padrão” em Java?

Antes de aprender a usar Scanner ou BufferedReader, é importante entender o que realmente significa “entrada padrão” em Java. Muitas confusões relacionadas à entrada surgem ao pular este conceito básico.

2.1 O papel da entrada padrão (System.in)

Em Java, entrada padrão é a fonte de dados padrão que um programa lê ao iniciar. Essa fonte é representada pelo seguinte objeto:

System.in

Pontos principais sobre System.in:

  • Ele representa um fluxo de entrada fornecido pelo sistema operacional
  • Seu tipo é InputStream
  • O próprio Java não decide de onde vem a entrada

Em outras palavras, System.in é simplesmente um fluxo de dados, não uma “API de teclado”.

2.2 Entrada padrão nem sempre é o teclado

Um equívoco muito comum é:

Standard input = keyboard input

Isso é apenas parcialmente verdadeiro.

Quando você executa um programa como este:

java Main

a entrada padrão está conectada ao teclado.

Entretanto, você também pode executá-lo assim:

java Main < input.txt

Neste caso:

  • A entrada vem de um arquivo
  • Não vem do teclado
  • Mas o Java ainda a lê através de System.in

Do ponto de vista do programa, não há diferença.

É por isso que a entrada padrão costuma ser descrita como:

“Qualquer dado que é alimentado no programa em tempo de execução”

2.3 Por que System.in é difícil de usar diretamente

Embora System.in seja poderoso, ele não é conveniente de usar diretamente.

A razão é simples:

  • System.inbytes brutos
  • Ele não entende: wp:list /wp:list

    • Linhas
    • Números
    • Espaços
    • Codificação de texto

Exemplo:

InputStream in = System.in;

Neste nível, você lida apenas com bytes, não com valores significativos.

É por isso que o Java fornece classes wrapper que convertem a entrada bruta em dados utilizáveis.

2.4 Camadas de Manipulação de Entrada no Java

O processamento de entrada em Java pode ser entendido como uma estrutura em camadas.

[ Input source (keyboard, file, pipe) ]
                ↓
           System.in (InputStream)
                ↓
      Input helper classes
        ├ Scanner
        ├ BufferedReader
        └ Fast input implementations

Cada camada tem uma responsabilidade clara:

  • System.in wp:list /wp:list
    * Fluxo de bytes de baixo nível
  • Scanner wp:list /wp:list
    * Entrada baseada em tokens fácil (lenta mas simples)
  • BufferedReader wp:list /wp:list
    * Entrada baseada em linhas rápida
  • FastScanner wp:list /wp:list
    * Entrada numérica focada em desempenho

Entender essa estrutura explica por que existem múltiplos métodos de entrada.

2.5 Por que o Java tem múltiplos métodos de entrada

Java é usado em muitos contextos diferentes:

  • Educação
  • Sistemas corporativos
  • Ferramentas de linha de comando
  • Programação competitiva

Cada contexto tem prioridades diferentes:

  • Facilidade de uso
  • Legibilidade
  • Desempenho
  • Estabilidade

Por isso, o Java não impõe um único método de entrada “melhor”.
Em vez disso, ele oferece várias ferramentas para diferentes necessidades.

2.6 O que vem a seguir

Na próxima seção, começaremos a usar Scanner, a forma mais amigável para iniciantes de ler a entrada padrão.

Você aprenderá:

  • Como ler strings
  • Como ler números
  • Armadilhas comuns que confundem iniciantes

Isso o preparará para entender métodos de entrada mais rápidos mais tarde.

3. Formas comuns de ler a entrada padrão em Java (Visão geral)

Agora que você entende o que é a entrada padrão, vamos ver as três principais maneiras de lê-la em Java.
Antes de mergulhar nos detalhes do código, é importante ver a visão geral.

Cada método existe por uma razão, e escolher o correto economizará tempo e frustração.

3.1 Scanner: a opção mais fácil e amigável para iniciantes

Scanner costuma ser a primeira classe de entrada que os iniciantes em Java aprendem.

Scanner sc = new Scanner(System.in);

Com esta única linha, você pode ler facilmente:

  • Strings
  • Inteiros
  • Números de ponto flutuante

Principais recursos do Scanner

  • Prós wp:list /wp:list
    * Muito fácil de escrever e entender
    * Lê valores diretamente como tipos Java
    * Amplamente usado em tutoriais e livros

  • Contras wp:list /wp:list
    * Lento para grandes volumes de entrada
    * Possui alguns comportamentos complicados que iniciantes frequentemente encontram

Quando o Scanner é uma boa escolha

  • Aprendendo Java
  • Programas pequenos
  • Requisitos de entrada simples

Se o seu objetivo é entender a sintaxe e lógica do Java, Scanner é um ótimo ponto de partida.

3.2 BufferedReader: Rápido e Confiável para Aplicações Reais

BufferedReader é a escolha padrão uma vez que o tamanho da entrada ou o desempenho se tornam importantes.

BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in)
);

Diferente do Scanner, BufferedReader foca em ler linhas inteiras de forma eficiente.

Principais características do BufferedReader

  • Prós wp:list /wp:list

    • Muito mais rápido que o Scanner
    • Comportamento previsível e estável
    • Adequado para entradas grandes
    • Contras wp:list /wp:list

    • Requer análise manual

    • Código ligeiramente mais complexo

Quando o BufferedReader é uma boa escolha

  • Aplicações práticas
  • Processamento em lote
  • Problemas de programação com muitas linhas de entrada

BufferedReader é frequentemente considerado a escolha profissional padrão.

3.3 Entrada Rápida (FastScanner): Para Programação Competitiva

Na programação competitiva, até mesmo o BufferedReader pode ser lento demais.

Para resolver isso, muitos desenvolvedores usam classes personalizadas de entrada rápida, frequentemente chamadas de FastScanner.

Características da entrada rápida

  • Lê bytes brutos usando buffers
  • Evita a criação desnecessária de objetos
  • Converte números manualmente

Prós e contras

  • Prós wp:list /wp:list

    • Extremamente rápido
    • Ideal para tamanhos de entrada massivos
    • Contras wp:list /wp:list

    • Difícil de ler

    • Difícil de depurar
    • Não adequado para aplicações regulares

Quando usar entrada rápida

  • Programação competitiva
  • Limites de tempo muito rigorosos
  • Tamanhos de entrada enormes

No desenvolvimento de software normal, a entrada rápida raramente é necessária.

3.4 Tabela de Comparação Rápida

MethodEase of UseSpeedTypical Use
ScannerVery highLowLearning, small programs
BufferedReaderMediumHighReal applications
FastScannerLowVery highCompetitive programming

Esta tabela sozinha pode ajudá-lo a decidir qual ferramenta usar.

3.5 Como Decidir Quando Você Não Tem Certeza

Se você não tem certeza de qual método escolher, siga esta regra:

  1. Isso é para aprendizado ou um programa pequeno? wp:list /wp:list

    • Sim → Scanner 2. A entrada é grande ou o desempenho é importante? wp:list /wp:list

    • Sim → BufferedReader 3. Isso é um problema de programação competitiva? wp:list /wp:list

    • Sim → FastScanner

A maioria dos casos do mundo real é resolvida perfeitamente com BufferedReader.

3.6 O Que Vem a Seguir

Na próxima seção, focaremos em como usar o Scanner corretamente.

Você aprenderá:

  • Como ler strings
  • Como ler números
  • Armadilhas comuns do Scanner e como evitá-las

Isso o ajudará a escrever código de manipulação de entrada correto desde o início.

4. Lendo Entrada Padrão com Scanner (Do Básico a Dicas Práticas)

Nesta seção, focaremos no Scanner, a forma mais amigável para iniciantes de ler entrada padrão em Java.
Não mostraremos apenas como usá-lo, mas também explicaremos por que certos problemas ocorrem, para que você possa evitar erros comuns.

4.1 Lendo uma Linha de Texto (nextLine)

O caso de uso mais simples é ler uma linha completa de texto.

Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
System.out.println(line);
  • nextLine()tudo até a quebra de linha
  • Espaços dentro da linha são preservados

Exemplo de entrada:

Hello Java World

Resultado:

Hello Java World

Este método é ideal quando você quer ler frases ou texto de forma livre.

4.2 Lendo Números (nextInt, nextLong, etc.)

Uma das maiores vantagens do Scanner é que ele pode ler números diretamente.

int n = sc.nextInt();
long x = sc.nextLong();
double d = sc.nextDouble();

Se a entrada for:

42

O valor 42 é armazenado como um int sem qualquer conversão manual.

Por que isso é conveniente

  • Não é necessário Integer.parseInt
  • Menos código boilerplate
  • Fácil de entender para iniciantes

4.3 A Armadilha Famosa: nextInt() Seguido de nextLine()

Essa é uma das falhas mais comuns relacionadas ao Scanner.

int n = sc.nextInt();
String s = sc.nextLine(); // often becomes empty

.

Por que isso acontece?

  • nextInt() lê apenas o número
  • O caractere de nova linha ( \n ) permanece no buffer de entrada
  • nextLine() lê essa nova linha restante

Como resultado, s torna‑se uma string vazia.

4.4 Como corrigir o problema do nextLine()

A solução padrão é consumir a nova linha restante.

int n = sc.nextInt();
sc.nextLine(); // consume newline
String s = sc.nextLine();

Esse padrão é extremamente comum e vale a pena memorizar.

Alternativamente, você pode evitar misturar nextInt() e nextLine() completamente lendo tudo como strings.

4.5 Lendo valores separados por espaço

O Scanner trata automaticamente espaços e quebras de linha como separadores.

Entrada:

10 20 30

Código:

int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();

Isso funciona sem nenhuma lógica adicional.

Custo oculto

  • O Scanner usa expressões regulares internamente
  • Isso o torna flexível, mas mais lento para grandes entradas

4.6 Lendo até o fim da entrada (EOF)

Às vezes você precisa ler a entrada até que não haja mais dados.

while (sc.hasNext()) {
    int value = sc.nextInt();
    System.out.println(value);
}

Ou para entrada baseada em linhas:

while (sc.hasNextLine()) {
    String line = sc.nextLine();
    System.out.println(line);
}

Esse padrão é útil para entrada de arquivos e juízes online.

4.7 Por que o Scanner fica lento com grandes entradas

O Scanner é lento não porque seja “ruim”, mas porque foi projetado para segurança e flexibilidade.

As razões incluem:

  • Análise de expressões regulares
  • Conversão automática de tipos
  • Validação extensiva de entrada

Para pequenas entradas, esse custo é insignificante.
Para grandes entradas, torna‑se um problema sério de desempenho.

4.8 Quando o Scanner é a escolha certa

O Scanner é uma boa escolha quando:

  • Você está aprendendo Java
  • O tamanho da entrada é pequeno
  • A legibilidade do código importa mais que a velocidade

Se o desempenho se tornar uma preocupação, é hora de mudar para BufferedReader.

4.9 O que vem a seguir

Na próxima seção, apresentaremos BufferedReader, a solução padrão para entrada rápida e confiável.

Você aprenderá:

  • Entrada baseada em linhas
  • Análise manual de números
  • Manipulação eficiente de grandes entradas

5. Lendo entrada padrão com BufferedReader (rápido e confiável)

Nesta seção, passamos para BufferedReader, que é amplamente usado em programas Java do mundo real e em desafios de programação.
Em comparação ao Scanner, requer um pouco mais de código, mas oferece um desempenho e controle muito melhores.

5.1 Exemplo mínimo: lendo uma única linha

A configuração básica para BufferedReader é a seguinte:

BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in)
);

String line = br.readLine();
System.out.println(line);
  • readLine() lê a entrada linha por linha
  • Retorna null quando não há mais entrada (EOF)

Esse comportamento claro torna a depuração muito mais fácil do que com o Scanner.

5.2 Lendo múltiplas linhas até EOF

Quando o número de linhas de entrada não é conhecido antecipadamente, esse padrão é padrão:

String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}

Por que isso funciona bem

  • null indica claramente o fim da entrada
  • Nenhuma verificação extra é necessária
  • Muito comum em entrada de arquivos e juízes online

5.3 Convertendo strings para números

Ao contrário do Scanner, BufferedReader sempre lê strings, portanto a conversão numérica é manual.

int n = Integer.parseInt(br.readLine());
long x = Long.parseLong(br.readLine());
double d = Double.parseDouble(br.readLine());

Nota importante

  • Se a entrada não for um número válido, ocorrerá uma NumberFormatException
  • Isso obriga você a ser preciso sobre o formato da entrada

Embora isso possa parecer inconveniente no início, leva a programas mais previsíveis.

5.4 Manipulando entrada separada por espaço

Valores separados por espaço são extremamente comuns.

Entrada:

10 20 30

Método 1: Usando split (Prioridade à Legibilidade)

String[] parts = br.readLine().split(" ");
int a = Integer.parseInt(parts[0]);
int b = Integer.parseInt(parts[1]);
int c = Integer.parseInt(parts[2]);
  • Fácil de entender
  • Adequado para entradas pequenas a médias
  • Ligeiramente mais lento devido às expressões regulares

Método 2: Usando StringTokenizer (Orientado para Desempenho)

StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
  • Mais rápido que split
  • Muito comum em programação competitiva
  • Ainda perfeitamente válido no Java moderno

5.5 Lendo Linhas Repetidas Separadas por Espaços

Exemplo de entrada:

3
10 20
30 40
50 60

Código:

int n = Integer.parseInt(br.readLine());

for (int i = 0; i < n; i++) {
    StringTokenizer st = new StringTokenizer(br.readLine());
    int x = Integer.parseInt(st.nextToken());
    int y = Integer.parseInt(st.nextToken());
    System.out.println(x + y);
}

Este padrão aparece frequentemente em:

  • Testes de programação
  • Problemas de algoritmos
  • Ferramentas de processamento de dados

5.6 Lidando com IOException

Os métodos de BufferedReader lançam exceções verificadas, então você deve tratá-las.

Abordagem Simples (aprendizado / concursos):

public static void main(String[] args) throws Exception {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
}

Abordagem no Estilo de Produção:

try {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
} catch (IOException e) {
    e.printStackTrace();
}

Para iniciantes, a primeira abordagem geralmente é suficiente.

5.7 Por Que o BufferedReader É Rápido

O BufferedReader é rápido porque:

  1. Ele lê dados em grandes blocos (bufferização)
  2. Ele evita a análise de expressões regulares
  3. Ele permite que você controle como os dados são interpretados

Em resumo, ele separa:

  • Leitura
  • Análise

Este design é a diferença chave em relação ao Scanner.

5.8 Resumo: Scanner vs BufferedReader

FeatureScannerBufferedReader
Ease of useVery highMedium
SpeedLowHigh
Line-based inputWeakExcellent
Numeric parsingAutomaticManual
Real-world usageLimitedVery common

5.9 O Que Vem a Seguir

Na próxima seção, exploraremos técnicas de entrada rápida usadas em programação competitiva.

Você aprenderá:

  • Por que até o BufferedReader pode ser muito lento
  • Como a entrada rápida funciona conceitualmente
  • Uma implementação prática de FastScanner

6. Entrada Rápida para Programação Competitiva (FastScanner)

Em programação competitiva, o tamanho da entrada pode ser tão grande que até o BufferedReader se torna um gargalo.
Esta seção explica por que a entrada rápida é necessária, como ela funciona e quando você deve (e não deve) usá-la.

6.1 Por Que o Scanner Causa Erros de Limite de Tempo

Problemas de programação competitiva frequentemente têm:

  • Centenas de milhares ou milhões de números
  • Limites de tempo rigorosos (1–2 segundos)
  • Ambientes de execução limitados

O Scanner realiza muitas verificações internamente:

  • Análise de expressões regulares
  • Conversão automática de tipos
  • Validação extensa

Essas funcionalidades são úteis para segurança — mas caras em termos de desempenho.
Como resultado, o Scanner frequentemente causa TLE (Time Limit Exceeded) em concursos.

6.2 Quando o BufferedReader Ainda Não É Suficiente

O BufferedReader é muito mais rápido que o Scanner, mas ainda:

  • Cria objetos String
  • Divide strings em tokens
  • Analisa números a partir de texto

Quando a entrada é extremamente grande, esses passos sozinhos podem ser muito lentos.

Isso leva a uma abordagem diferente:

Ler bytes brutos e converter números manualmente

6.3 Como a Entrada Rápida Funciona (Conceitualmente)

Técnicas de entrada rápida tipicamente seguem este processo:

  1. Ler um grande bloco de bytes de uma vez
  2. Armazená-los em um buffer de bytes
  3. Pular caracteres desnecessários (espaços, quebras de linha)
  4. Converter dígitos diretamente em números
  5. Evitar criar objetos desnecessários

Isso minimiza:

  • Alocação de memória
  • Coleta de lixo
  • Sobrecarga de CPU

6.4 Implementação Prática de FastScanner

Abaixo está um FastScanner minimalista e prático adequado para concursos.

static class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1 << 16];
    private int ptr = 0, len = 0;

    private int readByte() throws IOException {
        if (ptr >= len) {
            len = in.read(buffer);
            ptr = 0;
            if (len <= 0) return -1;
        }
        return buffer[ptr++];
    }

    int nextInt() throws IOException {
        int c;
        do {
            c = readByte();
        } while (c <= ' ');

        boolean negative = false;
        if (c == '-') {
            negative = true;
            c = readByte();
        }

        int value = 0;
        while (c > ' ') {
            value = value * 10 + (c - '0');
            c = readByte();
        }
        return negative ? -value : value;
    }
}

Exemplo de uso:

FastScanner fs = new FastScanner();
int n = fs.nextInt();

Esta abordagem é extremamente rápida para entrada numérica grande.

6.5 Limitações Importantes do FastScanner

Entrada rápida não é uma solução universal.

Desvantagens:

  • Difícil de ler e manter
  • Difícil de depurar
  • Não adequado para entrada com muito texto
  • Exagerado para a maioria das aplicações

Use o FastScanner apenas quando necessário, tipicamente em concursos.

6.6 Resumo dos Métodos de Entrada

  • Scanner → Aprendizado, entrada pequena
  • BufferedReader → Aplicações reais, entrada grande
  • FastScanner → Apenas para programação competitiva

Escolher a ferramenta mais simples que atenda às suas necessidades de desempenho é sempre a melhor opção.

6.7 O Que Vem a Seguir

Na próxima seção, resumiremos como escolher o método de entrada correto usando um guia de decisão simples.

7. Como Escolher o Método de Entrada Correto (Guia de Decisão Rápida)

Até agora, você viu várias maneiras de lidar com a entrada padrão em Java.
Esta seção ajuda você a decidir rápida e confiantemente qual método usar em situações reais.

7.1 Para Aprendizado e Programas Pequenos

Recomendado: Scanner

Por que o Scanner funciona bem aqui

  • Fácil de ler e escrever
  • Boilerplate mínimo
  • Correspondente à maioria dos tutoriais para iniciantes

Cenários típicos:

  • Aprendizado dos fundamentos de Java
  • Pequenas ferramentas de linha de comando
  • Exercícios com tamanho de entrada limitado
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    

Se seu programa lê apenas uma pequena quantidade de entrada, o Scanner é perfeitamente adequado.

7.2 Para Entrada Grande e Desempenho Estável

Recomendado: BufferedReader

Por que o BufferedReader é a escolha profissional padrão

  • Rápido e previsível
  • Funciona bem com entrada grande
  • Fácil de controlar a lógica de análise da entrada

Cenários típicos:

  • Aplicações do mundo real
  • Jobs em lote
  • Problemas de programação com muitas linhas de entrada
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
    

Se você não tem certeza e o desempenho importa, BufferedReader é a opção mais segura.

7.3 Para Programação Competitiva e Tamanhos de Entrada Extremos

Recomendado: FastScanner

Por que o FastScanner existe

  • Projetado para evitar TLE
  • Lida eficientemente com entrada numérica massiva

Cenários típicos:

  • Concursos de programação competitiva
  • Problemas com limites de tempo muito restritos
  • Conjuntos de dados extremamente grandes
    FastScanner fs = new FastScanner();
    int n = fs.nextInt();
    

Fora da programação competitiva, essa abordagem geralmente é desnecessária.

7.4 Fluxo de Decisão Simples

Em caso de dúvida, siga esta lógica:

  1. É para aprendizado ou um script pequeno? → Use Scanner
  2. A entrada é grande ou o desempenho é importante? → Use BufferedReader
  3. É um problema de concurso com limites de tempo estritos? → Use FastScanner

Na prática, a maioria dos programas Java se enquadra no passo 2.

7.5 Equívocos Comuns

“O método mais rápido é sempre o melhor”

Isso é falso.

  • Entrada mais rápida reduz a legibilidade
  • Código complexo aumenta o risco de bugs
  • Manutenção se torna mais difícil

.Sempre prefira o método mais simples que atenda aos seus requisitos.

“Scanner nunca deve ser usado”

Também é falso.

Scanner é uma excelente ferramenta de aprendizado e perfeitamente válido para tarefas pequenas.

7.6 O que vem a seguir

Na próxima seção, veremos erros comuns e dicas de solução de problemas relacionados à entrada padrão em Java.

Você aprenderá:

  • Por que a entrada se comporta de forma inesperada
  • Como corrigir erros comuns de análise
  • Como diagnosticar problemas de desempenho

8. Erros Comuns e Solução de Problemas

Mesmo quando você entende o básico da entrada padrão em Java, pequenos erros podem causar bugs confusos ou problemas de desempenho.
Esta seção reúne os problemas mais comuns, explica por que eles acontecem e mostra como corrigi‑los.

8.1 A Entrada Parece ser Ignorada ou Ausente

Sintomas

  • Uma variável do tipo string fica vazia
  • A entrada é ignorada sem aguardar a digitação do usuário

Causa típica

Isso geralmente ocorre ao misturar nextInt() (ou métodos semelhantes) com nextLine() no Scanner.

int n = sc.nextInt();
String s = sc.nextLine(); // becomes empty

Solução

Consuma a quebra de linha restante antes de chamar nextLine().

int n = sc.nextInt();
sc.nextLine(); // consume newline
String s = sc.nextLine();

Alternativamente, use BufferedReader e faça a análise manualmente.

8.2 O Programa Fica Esperando para Sempre por Entrada

Sintomas

  • O programa não termina
  • A submissão em um juiz online nunca finaliza

Causa típica

  • O programa espera mais entrada do que foi fornecida
  • EOF (fim de arquivo) não é tratado corretamente

Solução

Use loops de entrada que reconheçam EOF.

String line;
while ((line = br.readLine()) != null) {
    // process line
}

Sempre verifique duas vezes a especificação do formato de entrada.

8.3 NumberFormatException ao Analisar Números

Sintomas

  • O programa falha ao converter strings em números
    int n = Integer.parseInt(line);
    

Causas típicas

  • Espaços à esquerda ou à direita
  • Linhas vazias
  • Caracteres inesperados na entrada

Solução

Limpe a entrada antes de analisá‑la.

line = line.trim();
int n = Integer.parseInt(line);

Também verifique se o formato da entrada corresponde às suas expectativas.

8.4 split() Produz Resultados Inesperados

Sintomas

  • Número errado de tokens
  • Strings vazias no array resultante

Causa típica

Múltiplos espaços entre os valores.

String[] parts = line.split(" ");

Solução

Use uma expressão regular que trate múltiplos espaços.

String[] parts = line.trim().split("\\s+");

Isso funciona para um ou mais espaços, tabulações ou quebras de linha.

8.5 O Programa Está Muito Lento (Time Limit Exceeded)

Sintomas

  • O programa funciona localmente, mas falha em competições
  • O tempo de execução ultrapassa os limites

Causas típicas

  • Uso de Scanner para entrada grande
  • Uso excessivo de split()
  • Chamadas frequentes a System.out.println()

Soluções

  • Troque para BufferedReader
  • Use StringTokenizer em vez de split
  • Agrupe a saída usando StringBuilder e PrintWriter

Frequentemente, a velocidade da entrada é o verdadeiro gargalo, não o algoritmo.

8.6 Confusão Sobre Exceções Verificadas (IOException)

Sintomas

  • Erros de compilação relacionados a IOException
  • Incerteza sobre onde adicionar try-catch

Solução Simples (Aprendizado / Competições)

public static void main(String[] args) throws Exception {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
}

Solução de Produção

Use blocos try-catch adequados e trate os erros de forma elegante.

8.7 Problemas de Codificação de Caracteres

Sintomas

  • Texto não‑inglês aparece corrompido
  • Caracteres inesperados na entrada

Causa

Incompatibilidade entre a codificação da entrada e a codificação padrão do Java.

Solução

Especifique a codificação explicitamente.

BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in, "UTF-8")
);

Isso é especialmente importante ao ler arquivos ou entrada multilíngue.

8.8 Lista de Verificação Rápida de Solução de Problemas

Quando a entrada se comporta de forma inesperada, verifique o seguinte:

  1. Seu código corresponde exatamente ao formato de entrada?
  2. Você está lidando com quebras de linha e espaços corretamente?
  3. Você está misturando métodos do Scanner com segurança?
  4. O tamanho da entrada é muito grande para o Scanner?
  5. Você está lidando com EOF corretamente?

Verificar sistematicamente esses pontos resolve a maioria dos problemas.

8.9 O Que Vem a Seguir

Na próxima seção, responderemos perguntas frequentes (FAQ) sobre a entrada padrão do Java.

Isso ajudará a esclarecer dúvidas restantes e reforçar as melhores práticas.

9. Perguntas Frequentes (FAQ)

Esta seção responde às perguntas mais comuns relacionadas à entrada padrão do Java, especialmente aquelas que iniciantes e desenvolvedores intermediários costumam fazer.

9.1 Qual é Melhor: Scanner ou BufferedReader?

Depende do seu objetivo.

  • Use Scanner se: wp:list /wp:list

    • Você está aprendendo Java
    • O tamanho da entrada é pequeno
    • Legibilidade é mais importante que desempenho
    • Use BufferedReader se: wp:list /wp:list

    • O tamanho da entrada é grande

    • Desempenho importa
    • Você quer um comportamento previsível

Se você não tem certeza, BufferedReader geralmente é a escolha mais segura a longo prazo.

9.2 É Verdade que o Scanner é Lento?

Sim, para entradas grandes.

O Scanner foi projetado para:

  • Segurança
  • Flexibilidade
  • Facilidade de uso

Essas características o tornam mais lento ao processar grandes quantidades de dados.
Para entradas pequenas, a diferença é insignificante.

9.3 Por que nextLine() Retorna uma String Vazia?

Isso acontece quando nextLine() é chamado depois de nextInt() ou métodos semelhantes.

Razão:

  • nextInt() não consome o caractere de nova linha
  • nextLine() lê a nova linha restante

Solução:

sc.nextLine(); // consume newline

Ou evite misturar métodos de entrada baseados em tokens e baseados em linhas.

9.4 Devo Usar split() ou StringTokenizer?

  • Use split() quando: wp:list /wp:list

    • A entrada é pequena
    • Legibilidade importa
    • Use StringTokenizer quando: wp:list /wp:list

    • A entrada é grande

    • Desempenho é importante

Na programação competitiva, StringTokenizer ainda é amplamente usado.

9.5 Como Ler Entrada Até EOF?

Com BufferedReader:

String line;
while ((line = br.readLine()) != null) {
    // process input
}

Com Scanner:

while (sc.hasNext()) {
    // process input
}

O tratamento de EOF é comum em entrada de arquivos e em juízes online.

9.6 Posso Usar FastScanner em Aplicações Reais?

Não é recomendado.

FastScanner:

  • É difícil de ler
  • É difícil de manter
  • É otimizado apenas para concursos

Para aplicações reais, BufferedReader é o melhor equilíbrio entre velocidade e clareza.

9.7 Sempre Preciso Tratar Exceções?

  • Para aprendizado e concursos: public static void main(String[] args) throws Exception é aceitável.
  • Para código de produção: wp:list /wp:list

    • Use try-catch adequado
    • Trate erros explicitamente

9.8 Entrada é Rápida, mas Saída é Lenta. O Que Fazer?

Otimize a saída também.

  • Evite chamadas frequentes a System.out.println()
  • Use StringBuilder
  • Use PrintWriter para saída em buffer

O desempenho de entrada e saída deve ser otimizado juntos.

9.9 O Que Vem a Seguir

Na seção final, resumiremos tudo e reiteraremos as conclusões principais.

10. Resumo Final

Neste artigo, exploramos a entrada padrão do Java desde conceitos para iniciantes até técnicas avançadas usadas em programação competitiva.
Vamos concluir revisando os pontos mais importantes.

10.1 Os Três Principais Pontos

  • Entrada pequena ou fins de aprendizadoScanner
  • Entrada grande ou aplicações reaisBufferedReader
  • Programação competitiva e tamanhos de entrada extremosFastScanner

Escolher a ferramenta certa para a situação certa é muito mais importante do que usar o método mais rápido em todos os lugares.

10.2 Como Parar de Ficar Confuso com o Tratamento de Entrada

A maior parte da confusão em torno da entrada em Java vem da falta de compreensão de:

  • Por que existem múltiplos métodos de entrada
  • Quais são os trade-offs de cada método
  • Quando o desempenho realmente importa

Uma vez que você veja o tratamento de entrada como uma escolha de design, a confusão desaparece.

10.3 Caminho de Aprendizado Recomendado para Iniciantes

Se você é novo em Java, siga esta progressão:

  1. Aprenda entrada usando Scanner
  2. Passe para BufferedReader para melhor desempenho e controle
  3. Aprenda técnicas de entrada rápida apenas se você entrar em programação competitiva

Esse caminho constrói tanto confiança quanto hábitos corretos.

10.4 Dicas Práticas para Uso no Mundo Real

  • Sempre confirme o formato da entrada
  • Tenha cuidado com quebras de linha e espaços
  • Otimize entrada e saída juntos
  • Suspeite da velocidade de entrada se o desempenho for ruim

Esses hábitos simples previnem a maioria dos bugs relacionados à entrada.

10.5 Para Onde Ir em Seguida

Para aprofundar suas habilidades em Java após dominar a entrada padrão, considere aprender:

  • Otimização de saída padrão ( PrintWriter , StringBuilder )
  • Fundamentos de tratamento de exceções
  • Coleções ( List , Map ) combinadas com entrada
  • Design de entrada/saída para algoritmos

A entrada padrão em Java pode parecer simples, mas é uma habilidade essencial que suporta todo programa Java que você escreve.
Dominá-la tornará seu código mais rápido, limpo e confiável.