Plano Estudos Java
Plano Estudos Java
Este plano de estudos foi elaborado para guiá-lo no aprendizado de Java do zero, com
foco em conceitos fundamentais e prática constante. O cronograma está dividido em 4
semanas, com tópicos diários, exercícios e mini-projetos semanais para consolidar o
conhecimento.
Teoria:
* O que é Java? História e aplicações.
* JVM, JRE e JDK (explicação das abreviações).
* Instalação do JDK e configuração do ambiente (variáveis de ambiente).
* Primeiro programa Java: "Hello, World!".
* Estrutura básica de um programa Java: public static void main(String[] args) .
Abreviações:
* JVM (Java Virtual Machine): Máquina virtual que executa o bytecode Java. É a
responsável por tornar o Java uma linguagem "write once, run anywhere" (escreva uma
vez, execute em qualquer lugar).
* JRE (Java Runtime Environment): Ambiente de tempo de execução Java. Contém a
JVM e as bibliotecas necessárias para executar aplicações Java.
* JDK (Java Development Kit): Kit de desenvolvimento Java. Inclui o JRE, o
compilador Java ( javac ) e outras ferramentas para desenvolver aplicações Java.
Exercícios:
1. Instale o JDK em seu computador e configure as variáveis de ambiente.
2. Crie um programa Java que imprima seu nome completo no console.
Dia 2: Variáveis, Tipos de Dados e Operadores
Teoria:
* Declaração e inicialização de variáveis.
* Tipos de dados primitivos (int, double, boolean, char, etc.) e seus usos.
* Operadores aritméticos (+, -, *, /, %), de atribuição (=, +=, etc.), relacionais (==, !=, <, >,
<=, >=) e lógicos (&&, ||, !).
* Conversão de tipos (casting).
Exercícios:
1. Crie um programa que declare duas variáveis do tipo double , calcule a média entre
elas e imprima o resultado.
2. Escreva um programa que calcule o resto da divisão de dois números inteiros e
verifique se o resultado é par ou ímpar (usando operador de módulo e condicional).
Teoria:
* Tomada de decisões com if , else if e else .
* Operadores lógicos para combinar condições.
* Estrutura switch para múltiplas opções.
switch (diaDaSemana) {
case "Segunda":
System.out.println("Dia de começar a semana!");
break;
case "Terça":
case "Quarta":
case "Quinta":
System.out.println("Meio da semana.");
break;
case "Sexta":
System.out.println("Sextou!");
break;
default:
System.out.println("Fim de semana.");
}
}
}
Exercícios:
1. Crie um programa que receba a nota de um aluno (0 a 100) e imprima se ele foi
aprovado (>= 70), em recuperação (>= 50 e < 70) ou reprovado (< 50).
2. Escreva um programa que, dado um número de 1 a 7, imprima o dia da semana
correspondente (1 para Domingo, 2 para Segunda, etc.) usando a estrutura switch .
Teoria:
* Laço for para iterações com número conhecido de repetições.
* Laço while para repetições baseadas em uma condição.
* Laço do-while para garantir que o bloco de código seja executado pelo menos uma
vez.
* Instruções break e continue .
// Loop while
int contador = 0;
while (contador < 3) {
System.out.println("Contador while: " + contador);
contador++;
}
// Loop do-while
int j = 0;
do {
System.out.println("Contador do-while: " + j);
j++;
} while (j < 2);
}
}
Exercícios:
1. Crie um programa que imprima todos os números pares de 1 a 20 usando um laço
for .
2. Escreva um programa que solicite ao usuário um número inteiro positivo. O programa
deve continuar pedindo até que um número positivo seja inserido, usando um laço do-
while .
Teoria:
* O que são arrays? Declaração, inicialização e acesso a elementos.
* Arrays unidimensionais.
* Introdução a métodos (funções): declaração, parâmetros e retorno.
* Chamada de métodos.
Exercícios:
1. Crie um programa que declare um array de strings com 5 nomes. Imprima cada nome
do array usando um laço for-each .
2. Escreva um método que receba um array de inteiros como parâmetro e retorne o
maior valor presente no array. Teste o método em seu programa principal.
Requisitos:
1. O programa deve solicitar ao usuário o número de notas a serem inseridas.
2. Em seguida, deve solicitar cada nota individualmente.
3. As notas devem ser armazenadas em um array.
4. O programa deve calcular a média das notas.
5. Com base na média, deve informar se o aluno foi aprovado (média >= 70) ou
reprovado.
6. Utilize estruturas condicionais e de repetição aprendidas durante a semana.
7. Crie um método para calcular a média das notas.
Semana 2: Orientação a Objetos e Classes Essenciais
Teoria:
* O que é POO? Pilares: Encapsulamento, Herança, Polimorfismo, Abstração.
* Conceito de Classe e Objeto.
* Definição de atributos (variáveis de instância) e métodos (comportamentos).
* Construtores: criação de objetos.
* Palavra-chave this .
// Construtor
public Carro(String marca, String modelo, int ano) {
this.marca = marca;
this.modelo = modelo;
this.ano = ano;
}
// Método
public void exibirDetalhes() {
System.out.println("Marca: " + marca + ", Modelo: " + modelo + ", Ano: " + ano);
}
meuCarro.exibirDetalhes();
outroCarro.exibirDetalhes();
}
}
Exercícios:
1. Crie uma classe Pessoa com atributos nome , idade e cidade . Adicione um
construtor e um método apresentar() que imprima os detalhes da pessoa.
2. Crie dois objetos da classe Pessoa e chame o método apresentar() para cada um.
Teoria:
* Conceito de Encapsulamento: proteger os dados e expor apenas o necessário.
* Modificadores de acesso: public , private , protected , default (package-private).
* Métodos getters e setters para acessar e modificar atributos privados.
minhaConta.depositar(200.0);
minhaConta.sacar(50.0);
minhaConta.sacar(1500.0); // Tentativa de saque inválido
}
}
Exercícios:
1. Modifique a classe Pessoa do Dia 6 para que os atributos nome , idade e cidade
sejam private . Adicione getters e setters para cada um.
2. Crie um método fazerAniversario() na classe Pessoa que aumente a idade em 1.
Garanta que a idade não possa ser definida para um valor negativo usando o setter .
Dia 8: Herança
Teoria:
* Conceito de Herança: reutilização de código e hierarquia de classes.
* Palavras-chave extends e super .
* Sobrescrita de métodos ( @Override ).
* Classes Object (classe pai de todas as classes em Java).
@Override
public void fazerSom() {
System.out.println("Latido!");
}
Exercícios:
1. Crie uma classe Veiculo com atributos marca e ano . Crie um método acelerar() .
2. Crie uma classe CarroEsportivo que herde de Veiculo . Adicione um atributo
velocidadeMaxima e sobrescreva o método acelerar() para imprimir uma mensagem
diferente.
Teoria:
* Conceito de Polimorfismo: um objeto pode assumir muitas formas.
* Polimorfismo em tempo de compilação (sobrecarga de métodos).
* Polimorfismo em tempo de execução (sobrescrita de métodos).
* Classes Abstratas: o que são, quando usar, métodos abstratos.
* Interfaces: o que são, quando usar, diferença para classes abstratas.
// Interface
interface Forma {
double calcularArea();
}
@Override
public double calcularArea() {
return Math.PI * raio * raio;
}
}
// Classe Abstrata
abstract class Quadrilatero implements Forma {
// Atributos e métodos comuns a todos os quadriláteros
double lado1, lado2, lado3, lado4;
@Override
public double calcularArea() {
return largura * altura;
}
@Override
public void exibirTipo() {
System.out.println("Sou um Retângulo.");
}
}
Exercícios:
1. Crie uma interface Acao com um método executar() . Crie duas classes que
implementem essa interface: Caminhar e Correr . No método main , crie objetos de
ambas as classes e chame executar() .
2. Crie uma classe abstrata Funcionario com atributos nome e salario e um método
abstrato calcularSalarioAnual() . Crie duas classes concretas que herdem de
Funcionario : Gerente e Desenvolvedor , implementando o método abstrato de forma
diferente para cada um.
Teoria:
* Classe String : imutabilidade, métodos úteis (length, charAt, substring, equals, etc.).
* Classe Math : métodos para operações matemáticas (sqrt, pow, random, etc.).
* Classe Scanner : entrada de dados do usuário via console.
// Classe Math
double raizQuadrada = Math.sqrt(25.0);
System.out.println("Raiz quadrada de 25: " + raizQuadrada);
double potencia = Math.pow(2, 3);
System.out.println("2 elevado a 3: " + potencia);
int numeroAleatorio = (int) (Math.random() * 100); // Gera número entre 0 e 99
System.out.println("Número aleatório: " + numeroAleatorio);
// Classe Scanner
Scanner scanner = new Scanner(System.in); // Cria um objeto Scanner
Exercícios:
1. Crie um programa que solicite ao usuário uma frase e conte quantas vezes a letra 'a'
(maiúscula ou minúscula) aparece na frase.
2. Escreva um programa que simule um jogo de adivinhação. O programa deve gerar um
número aleatório entre 1 e 100. O usuário tenta adivinhar o número, e o programa
informa se o palpite foi muito alto, muito baixo ou correto. O jogo continua até o usuário
acertar.
Requisitos:
1. Crie uma classe Livro com atributos titulo , autor , anoPublicacao e disponivel
(boolean).
2. A classe Livro deve ter um construtor e métodos getters para todos os atributos.
Adicione um método emprestar() que mude o status disponivel para false e um
método devolver() que mude para true .
3. Crie uma classe Biblioteca que contenha um array de objetos Livro .
4. A classe Biblioteca deve ter métodos para:
* adicionarLivro(Livro livro) : adiciona um livro ao array.
* listarLivros() : imprime os detalhes de todos os livros na biblioteca.
* buscarLivroPorTitulo(String titulo) : busca um livro pelo título e retorna o objeto
Livro (ou null se não encontrado).
* emprestarLivro(String titulo) : busca o livro e, se disponível, o empresta.
* devolverLivro(String titulo) : busca o livro e o devolve.
5. No método main , crie uma instância da Biblioteca , adicione alguns livros, liste-os,
tente emprestar e devolver livros, e demonstre a funcionalidade de busca.
Teoria:
* Introdução às Collections API: List , Set , Map .
* Interface List : ArrayList e LinkedList .
* Adicionar, remover, acessar e iterar elementos em listas.
* Diferenças entre ArrayList e LinkedList .
import java.util.ArrayList;
import java.util.List;
// Adicionando elementos
nomes.add("Alice");
nomes.add("Bob");
nomes.add("Charlie");
nomes.add(1, "David"); // Adiciona na posição 1
// Acessando elementos
System.out.println("Primeiro nome: " + nomes.get(0));
// Removendo elementos
nomes.remove("Bob"); // Remove pelo valor
nomes.remove(0); // Remove pelo índice (Alice)
Exercícios:
1. Crie um ArrayList de números inteiros. Adicione 5 números, remova o terceiro
elemento e imprima a lista resultante.
2. Escreva um programa que leia uma lista de palavras do usuário até que ele digite
"fim". Armazene as palavras em um ArrayList e, ao final, imprima todas as palavras em
ordem alfabética.
Teoria:
* Interface Set : HashSet e LinkedHashSet .
* Características de um Set : não permite elementos duplicados, não garante ordem.
* Interface Map : HashMap e LinkedHashMap .
* Características de um Map : armazena pares chave-valor, chaves únicas.
import java.util.HashSet;
import java.util.HashMap;
import java.util.Set;
import java.util.Map;
// Exemplo de HashMap
Map<String, Integer> idades = new HashMap<>();
idades.put("João", 30);
idades.put("Maria", 25);
idades.put("Pedro", 35);
idades.put("João", 31); // Atualiza o valor para a chave "João"
Exercícios:
1. Crie um HashSet de números inteiros. Adicione alguns números, incluindo
duplicatas, e imprima o Set para verificar que as duplicatas foram ignoradas.
2. Crie um HashMap onde a chave é o nome de um país (String) e o valor é sua capital
(String). Adicione 3-4 pares país-capital e, em seguida, solicite ao usuário um país e
imprima sua capital. Se o país não for encontrado, informe ao usuário.
Teoria:
* O que são exceções? Erros em tempo de execução.
* Tipos de exceções: Checked vs. Unchecked (RuntimeException).
* Blocos try-catch-finally .
* Lançando exceções ( throw e throws ).
* Criando exceções personalizadas.
Exemplo de Código: Tratamento de Exceções
import java.util.InputMismatchException;
import java.util.Scanner;
try {
System.out.print("Digite um número inteiro: ");
int numero = scanner.nextInt();
System.out.println("Número digitado: " + numero);
} catch (InputMismatchException e) {
System.err.println("Erro: Entrada inválida. Por favor, digite um número
inteiro.");
// e.printStackTrace(); // Para depuração
} catch (ArithmeticException e) {
System.err.println("Erro: Divisão por zero não é permitida.");
} catch (Exception e) { // Captura qualquer outra exceção
System.err.println("Ocorreu um erro inesperado: " + e.getMessage());
} finally {
System.out.println("Bloco finally sempre é executado.");
scanner.close();
}
Exercícios:
1. Crie um programa que solicite ao usuário dois números. Realize a divisão do primeiro
pelo segundo. Utilize try-catch para tratar a exceção de ArithmeticException (divisão
por zero) e InputMismatchException (entrada não numérica).
2. Escreva um método que receba um array de inteiros e um índice. O método deve
retornar o elemento no índice especificado. Utilize try-catch para tratar a exceção
ArrayIndexOutOfBoundsException caso o índice seja inválido.
Teoria:
* Conceitos básicos de I/O: InputStream , OutputStream , Reader , Writer .
* Leitura de arquivos de texto: FileReader , BufferedReader .
* Escrita em arquivos de texto: FileWriter , BufferedWriter , PrintWriter .
* Tratamento de IOException .
* try-with-resources para fechar recursos automaticamente.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
// Lendo do arquivo
try (BufferedReader reader = new BufferedReader(new
FileReader(NOME_ARQUIVO))) {
String linha;
System.out.println("\nConteúdo do arquivo " + NOME_ARQUIVO + ":");
while ((linha = reader.readLine()) != null) {
System.out.println(linha);
}
} catch (IOException e) {
System.err.println("Erro ao ler do arquivo: " + e.getMessage());
}
}
}
Exercícios:
1. Crie um programa que solicite ao usuário algumas linhas de texto. O programa deve
salvar essas linhas em um arquivo chamado saida.txt . O usuário deve digitar "fim" para
parar a entrada.
2. Escreva um programa que leia o conteúdo do arquivo saida.txt criado no exercício
anterior e imprima cada linha no console, numerando-as (ex: "1: Esta é a primeira
linha.").
Teoria:
* java.util.Arrays : métodos para manipular arrays (sort, fill, copyOf, etc.).
* java.util.Collections : métodos utilitários para coleções (sort, shuffle, reverse, etc.).
* API de Data e Hora (Java 8+): LocalDate , LocalTime , LocalDateTime , Duration ,
Period , DateTimeFormatter .
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
// Adicionando/Subtraindo tempo
LocalDate amanha = hoje.plusDays(1);
System.out.println("Amanhã: " + amanha);
Exercícios:
1. Crie um programa que declare um array de 10 números inteiros aleatórios. Ordene o
array e imprima-o. Em seguida, embaralhe o array e imprima-o novamente.
2. Escreva um programa que calcule a sua idade exata em anos, meses e dias, dada a
sua data de nascimento e a data atual. Utilize a API de Data e Hora do Java 8+.
Requisitos:
1. Crie uma classe Tarefa com atributos descricao (String), dataVencimento
(LocalDate) e concluida (boolean).
2. A classe Tarefa deve ter um construtor e métodos getters e setters apropriados.
3. Crie uma classe GerenciadorTarefas que utilize um ArrayList<Tarefa> para
armazenar as tarefas.
4. O GerenciadorTarefas deve ter métodos para:
* adicionarTarefa(String descricao, LocalDate dataVencimento)
* listarTarefas() : imprime todas as tarefas, indicando se estão concluídas e a data de
vencimento.
* marcarTarefaConcluida(int indice)
* removerTarefa(int indice)
* salvarTarefas(String nomeArquivo) : salva as tarefas em um arquivo de texto (um
formato simples, como CSV ou um por linha).
* carregarTarefas(String nomeArquivo) : carrega as tarefas de um arquivo de texto.
5. No método main , implemente um menu interativo que permita ao usuário:
* Adicionar nova tarefa.
* Listar todas as tarefas.
* Marcar tarefa como concluída.
* Remover tarefa.
* Salvar tarefas em arquivo.
* Carregar tarefas de arquivo.
* Sair do programa.
6. Utilize tratamento de exceções para lidar com entradas inválidas do usuário e erros
de I/O.
Objetivo: Explorar tópicos mais avançados como Generics, Streams API, Programação
Funcional e introdução a JDBC para interação com banco de dados.
Teoria:
* O que são Generics? Vantagens: segurança de tipo em tempo de compilação,
eliminação de casts, reutilização de código.
* Classes e interfaces genéricas.
* Métodos genéricos.
* Wildcards ( ? ).
// Classe genérica
public class Caixa<T> {
private T conteudo;
public T getConteudo() {
return conteudo;
}
public void setConteudo(T conteudo) {
this.conteudo = conteudo;
}
// Método genérico
public static <U> void imprimirConteudo(Caixa<U> caixa) {
System.out.println("Conteúdo da caixa: " + caixa.getConteudo());
}
imprimirConteudo(caixaString);
imprimirConteudo(caixaInteger);
Exercícios:
1. Crie uma classe genérica Par<K, V> que armazene um par de valores (chave e valor).
Crie um construtor e métodos getK() e getV() .
2. Escreva um método genérico trocarElementos(List<T> lista, int i, int j) que troque
dois elementos de posição em uma lista genérica.
Teoria:
* Introdução à Streams API: processamento de coleções de forma declarativa e
funcional.
* Operações intermediárias (filter, map, sorted, distinct, limit, skip).
* Operações terminais (forEach, collect, reduce, count, min, max, anyMatch, allMatch,
noneMatch).
* Construindo pipelines de Stream.
Exercícios:
1. Dada uma lista de strings, use Streams para filtrar apenas as strings que começam
com a letra 'A' e, em seguida, imprima-as em ordem alfabética.
2. Dada uma lista de objetos Produto (com atributos nome e preco ), use Streams
para calcular o preço total de todos os produtos que custam mais de R$ 50,00.
Teoria:
* Conceitos de Programação Funcional: funções como cidadãos de primeira classe,
imutabilidade, efeitos colaterais.
* Expressões Lambda (Java 8+): sintaxe e uso.
* Interfaces Funcionais ( @FunctionalInterface ).
* Referências de Método.
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
@FunctionalInterface
interface OperacaoMatematica {
int calcular(int a, int b);
}
Exercícios:
1. Crie uma interface funcional VerificadorString com um método boolean
verificar(String s) . Implemente-a usando uma expressão lambda para verificar se uma
string é vazia.
2. Dada uma lista de números, use forEach com uma expressão lambda para imprimir
o quadrado de cada número.
Teoria:
* O que é JDBC? Conectando Java a bancos de dados.
* Driver JDBC.
* Classes principais: Connection , Statement , PreparedStatement , ResultSet .
* Executando consultas SQL (SELECT, INSERT, UPDATE, DELETE).
* Tratamento de SQLException .
(Nota: Para rodar este exemplo, você precisará adicionar a dependência do driver SQLite
ao seu projeto. Se estiver usando Maven, adicione ao pom.xml :)
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.45.1.0</version>
</dependency>
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
// 2. Estabelecer a conexão
Connection conn = DriverManager.getConnection(URL);
System.out.println("Conexão com o banco de dados estabelecida.");
// 4. Inserir dados
String sqlInsert = "INSERT INTO usuarios(nome, idade) VALUES(?, ?)";
PreparedStatement pstmtInsert = conn.prepareStatement(sqlInsert);
pstmtInsert.setString(1, "Alice");
pstmtInsert.setInt(2, 30);
pstmtInsert.executeUpdate();
pstmtInsert.setString(1, "Bob");
pstmtInsert.setInt(2, 25);
pstmtInsert.executeUpdate();
System.out.println("Dados inseridos.");
// 5. Consultar dados
String sqlSelect = "SELECT id, nome, idade FROM usuarios";
ResultSet rs = stmt.executeQuery(sqlSelect);
// 6. Atualizar dados
String sqlUpdate = "UPDATE usuarios SET idade = ? WHERE nome = ?";
PreparedStatement pstmtUpdate = conn.prepareStatement(sqlUpdate);
pstmtUpdate.setInt(1, 31);
pstmtUpdate.setString(2, "Alice");
pstmtUpdate.executeUpdate();
System.out.println("\nDados atualizados.");
// 7. Deletar dados
String sqlDelete = "DELETE FROM usuarios WHERE nome = ?";
PreparedStatement pstmtDelete = conn.prepareStatement(sqlDelete);
pstmtDelete.setString(1, "Bob");
pstmtDelete.executeUpdate();
System.out.println("Dados deletados.");
// 8. Fechar recursos
rs.close();
stmt.close();
pstmtInsert.close();
pstmtUpdate.close();
pstmtDelete.close();
conn.close();
System.out.println("Conexão e recursos fechados.");
} catch (SQLException e) {
System.err.println("Erro de SQL: " + e.getMessage());
} catch (Exception e) {
System.err.println("Ocorreu um erro inesperado: " + e.getMessage());
}
}
}
Exercícios:
1. Modifique o exemplo de JDBC para inserir mais 3 usuários na tabela usuarios .
2. Adicione uma funcionalidade para buscar um usuário pelo id e imprimir seus
detalhes.
Teoria:
* Introdução a Threads e Concorrência (conceitos básicos).
* Programação Assíncrona (Future, CompletableFuture - breve introdução).
* Introdução a Frameworks (Spring Boot, Hibernate - o que são e para que servem).
* Ferramentas de Build (Maven/Gradle - breve introdução).
* Testes Unitários (JUnit - conceitos básicos).
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(nome + ": Contagem = " + i);
try {
Thread.sleep(500); // Pausa a thread por 500 milissegundos
} catch (InterruptedException e) {
System.out.println(nome + " foi interrompida.");
}
}
System.out.println(nome + " finalizou.");
}
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(nome + ": Contagem = " + i);
try {
Thread.sleep(700); // Pausa a thread por 700 milissegundos
} catch (InterruptedException e) {
System.out.println(nome + " foi interrompida.");
}
}
System.out.println(nome + " finalizou.");
}
}
Exercícios:
1. Crie um programa que simule o download de 3 arquivos grandes em paralelo usando
Threads. Cada thread deve "baixar" um arquivo e imprimir uma mensagem quando
terminar.
2. Pesquise sobre o que é o Spring Boot e o Hibernate. Escreva um pequeno resumo (1-2
parágrafos) sobre a função de cada um no desenvolvimento Java.
Objetivo: Desenvolver uma aplicação de linha de comando que gerencie uma lista de
produtos, utilizando JDBC para persistência em banco de dados e Streams para
processamento de dados.
Requisitos:
1. Crie uma tabela produtos no banco de dados (SQLite, por exemplo) com colunas id
(PRIMARY KEY), nome (TEXT), preco (REAL) e quantidade (INTEGER).
2. Crie uma classe Produto com atributos correspondentes e métodos getters e
setters .
3. Crie uma classe ProdutoDAO (Data Access Object) que encapsule as operações de
banco de dados para a entidade Produto :
* adicionarProduto(Produto produto)
* listarTodosProdutos() : retorna uma List<Produto> .
* buscarProdutoPorId(int id) : retorna um Produto .
* atualizarProduto(Produto produto)
* deletarProduto(int id)
4. No método main , implemente um menu interativo que permita ao usuário:
* Adicionar novo produto.
* Listar todos os produtos (utilize Streams para filtrar e/ou ordenar a exibição, por
exemplo, produtos com estoque baixo).
* Buscar produto por ID.
* Atualizar produto (preço ou quantidade).
* Deletar produto.
* Sair do programa.
5. Utilize try-with-resources para gerenciar as conexões JDBC e tratamento de exceções
para erros de banco de dados e entrada do usuário.
6. Explore o uso de Streams para operações como:
* Calcular o valor total do estoque.
* Listar produtos com preço acima de um determinado valor.
* Encontrar o produto mais caro/barato.
Tutoriais e Artigos:
Observações Finais:
Esperamos que este plano de estudos seja um excelente ponto de partida para sua
jornada no mundo Java! Boa sorte e bons estudos!