Recapitulação - Container Genérico
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 58 de 87.
Desafio
FácilVamos construir um sistema de armazenamento versátil que reúne tudo o que você aprendeu sobre generics! Você criará uma classe Container que pode armazenar, recuperar e processar elementos de qualquer tipo, juntamente com métodos utilitários que demonstram wildcards em ação.
Você organizará seu código em três arquivos:
Container.java: Crie uma classe genéricaContainer<T>que gerencia uma coleção de itens. Seu container deve usar umArrayList<T>internamente para armazenar elementos. Inclua métodos paraadd(T item)um elemento,get(int index)para recuperar um elemento em uma posição específica,size()para retornar a contagem de itens eisEmpty()para verificar se o container não possui elementos. Adicione também um métodogetAll()que retorna a lista interna.ContainerUtils.java: Crie uma classe utilitária com métodos genéricos estáticos que funcionam com seus containers:printAll(Container<?> container)- Usa um wildcard ilimitado (unbounded wildcard) para imprimir todos os elementos em qualquer container, um por linha.countItems(Container<? extends Number> container)- Usa um wildcard com limite superior (upper bounded wildcard) para calcular a soma de todos os valores numéricos no container, retornando o resultado como umdouble.addDefaults(Container<? super Integer> container)- Usa um wildcard com limite inferior (lower bounded wildcard) para adicionar os inteiros 1, 2 e 3 a qualquer container que possa conter inteiros.<T> T getLastOrDefault(Container<T> container, T defaultValue)- Um método genérico que retorna o último elemento no container, ou o valor padrão se o container estiver vazio.Main.java: Reúna seu sistema de container genérico! Você receberá três entradas: uma palavra (String), um número inteiro e um double.Primeiro, crie um
Container<String>e adicione a palavra a ele duas vezes. Imprima"String container:"e useprintAllpara exibir seu conteúdo.Em seguida, crie um
Container<Double>e adicione o valor double a ele. Imprima uma linha em branco, depois"Number sum: "seguido pelo resultado decountItems.Depois, crie um
Container<Number>e chameaddDefaultsnele. Imprima uma linha em branco, depois"After adding defaults:"e useprintAllpara mostrar o conteúdo.Finalmente, crie um
Container<Integer>vazio e usegetLastOrDefaultcom sua entrada inteira como o padrão. Imprima uma linha em branco, depois"Last or default: "seguido pelo resultado.
Você receberá três entradas em ordem: uma palavra (String), um número inteiro e um double.
Este desafio combina classes genéricas, métodos genéricos, parâmetros de tipo limitados e todos os três tipos de wildcard. Observe como cada peça serve a um propósito diferente: a classe genérica fornece armazenamento seguro em relação ao tipo, os wildcards limitados permitem leitura e escrita flexíveis, e os métodos genéricos oferecem operações reutilizáveis em diferentes tipos de container!
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler as entradas
String word = scanner.nextLine();
int intValue = Integer.parseInt(scanner.nextLine());
double doubleValue = Double.parseDouble(scanner.nextLine());
// TODO: Criar um Container<String> e adicionar a palavra duas vezes
// Imprimir "String container:" e depois usar ContainerUtils.printAll()
// TODO: Criar um Container<Double> e adicionar o valor double
// Imprimir uma linha em branco, depois "Number sum: [sum]" usando ContainerUtils.countItems()
// TODO: Criar um Container<Number> e chamar ContainerUtils.addDefaults() nele
// Imprimir uma linha em branco, depois "After adding defaults:" e usar ContainerUtils.printAll()
// TODO: Criar um Container<Integer> vazio
// Usar ContainerUtils.getLastOrDefault() com intValue como padrão
// Imprimir uma linha em branco, depois "Last or default: [result]"
}
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Iterator