Fácil Java
Par genérico
Enunciado
Crie uma classe genérica Par<A, B> que armazena dois valores de tipos diferentes. Implemente métodos getPrimeiro(), getSegundo() e inverter() que retorna um novo Par<B, A> com os valores trocados. No main, crie um Par<String, Integer>, imprima os valores e depois o par invertido.
Requisitos
- A classe
Pardeve ser genérica com dois parâmetros de tipo. - O método
inverter()deve retornarPar<B, A>. - O programa deve imprimir os valores originais e os invertidos.
Código inicial
public class Main {
public static void main(String[] args) {
// TODO: criar Par<String, Integer> e testar
}
}
// TODO: declarar classe Par<A, B>
Saída esperada
Primeiro: olá, Segundo: 42
Invertido: 42, olá
Ver dica
Use new Par<>(segundo, primeiro) dentro de inverter().
Mostrar solução
public class Main {
public static void main(String[] args) {
Par<String, Integer> par = new Par<>("olá", 42);
System.out.println("Primeiro: " + par.getPrimeiro() + ", Segundo: " + par.getSegundo());
Par<Integer, String> invertido = par.inverter();
System.out.println("Invertido: " + invertido.getPrimeiro() + ", " + invertido.getSegundo());
}
}
class Par<A, B> {
private final A primeiro;
private final B segundo;
public Par(A primeiro, B segundo) {
this.primeiro = primeiro;
this.segundo = segundo;
}
public A getPrimeiro() { return primeiro; }
public B getSegundo() { return segundo; }
public Par<B, A> inverter() {
return new Par<>(segundo, primeiro);
}
}
Passo a passo
- Declaramos a classe
Par<A, B>com dois parâmetros de tipo, permitindo armazenar quaisquer tipos. - Os campos
primeiroesegundosão do tipoAeB, respectivamente, e sãofinalpara imutabilidade. - O construtor recebe valores dos tipos
AeBe os atribui. - Os getters retornam os valores com os tipos corretos, sem casts.
- O método
inverter()cria um novoPar<B, A>trocando a ordem dos argumentos. - No
main, instanciamosPar<String, Integer>e imprimimos os valores. - Chamamos
inverter()e imprimimos o novo par, mostrando a troca de tipos.
Por que funciona
A classe genérica permite que os tipos A e B sejam definidos no momento da instanciação, garantindo segurança de tipos. O método inverter() usa os mesmos parâmetros de tipo da classe, mas em ordem trocada, e o compilador verifica se os tipos estão corretos. Como os genéricos são apagados em tempo de execução (type erasure), não há custo adicional em runtime.
Erros comuns
- Esquecer de declarar os parâmetros de tipo na classe:
class Par { ... }causaria uso deObjecte perderia a segurança de tipos. - Tentar acessar
primeirodiretamente sem getter, mas como é privado, não compila. - No
main, usarnew Par("olá", 42)sem os tipos explícitos ainda funciona por inferência, mas é boa prática declarar. - Retornar
Par<A, B>eminverter()em vez dePar<B, A>causaria erro de tipo na atribuição.
Outra forma de resolver
Usar record (Java 16+) para simplificar:
record Par<A, B>(A primeiro, B segundo) {
Par<B, A> inverter() { return new Par<>(segundo, primeiro); }
}
Saída esperada
Primeiro: olá, Segundo: 42
Invertido: 42, olá