java - introdução a coleções e generics
Post on 26-May-2015
865 Views
Preview:
TRANSCRIPT
Java - Introdução a Coleções e Generics
Prof. Sérgio Souza Costa
Objetivo
• Prepararmos para entendermos como funciona o “framework collection” do Java.
Capítulo de hoje: Um programador C/C++ precisa lidar com coleções de dados em Java.
Para que estudar sobre o “framework collection” do Java se eu posso construir minhas próprias coleções ?
Aprendi nas aulas de estrutura de dados ☺
public class Pilha {int v[];int pos;public Pilha (int n) {
v = new int [n];pos = 0;
}public void empilha(int x) {
v[pos++] = x;}public int desempilha() {
return v[--pos] ;}
}
Olhem milha pilha. Muito fácil
public class Pilha {int v[];int pos;public Pilha (int n) {
v = new int [n];pos = 0;
}public void empilha(int x) {
v[pos++] = x;}public int desempilha() {
return v[--pos] ;}
}
Ok. Falta fazer uns testes, mas ....
public class Pilha {int v[];int pos;public Pilha (int n) {
v = new int [n];pos = 0;
}public void empilha(int x) {
v[pos++] = x;}public int desempilha() {
return v[--pos] ;}
}
Ok. Falta fazer uns testes, mas ....
Quais testes ele está se referindo ?
public class Teste {public static void main(String[] args) {
Pilha p = new Pilha (5);p.empilha(10);p.empilha(5);p.empilha(2);System.out.println(p.desempilha());System.out.println(p.desempilha());System.out.println(p.desempilha());
}}
Testando minha pilha. O que
acharam?
Para aulas de estrutura de dados está ok, mas esta tua pilha não é muito útil. Ela é restrita a um tipo de dado (
inteiro)
Sim. Isso é por que Java é uma linguagem que os métodos e variáveis tem que ter tipos
definido estaticamente.
Em C, eu usava *void para estruturas genéricas. Depois
bastava eu fazer um cast para um tipo específico.
Será que Java não tem algo similar ? O que
vocês acham ?
Yes. Como toda classe em Java herda de
Object, este poderia ser o tipo da minha pilha.
public class PilhaObjeto {Object v[];int pos;public PilhaObjeto (int n) {
v = new Object [n];pos = 0;
}public void empilha(Object x) {
v[pos++] = x;}public Object desempilha() {
return v[--pos] ;}
}
Pilha de Object
public static void main(String[] args) {PilhaObjeto p = new PilhaObjeto (5);p.empilha("Joao");p.empilha("Jose");p.empilha("Maria");String nome = (String) p.
desempilha();System.out.println("nome:"+nome);
}
Resolvido. O que acharam ?
public static void main(String[] args) {PilhaObjeto p = new PilhaObjeto (5);p.empilha("Joao");p.empilha("Jose");p.empilha(10);String nome = (String) p.
desempilha();System.out.println("nome:"+nome);
}
Mais um teste ...
public static void main(String[] args) {PilhaObjeto p = new PilhaObjeto (5);p.empilha("Joao");p.empilha("Jose");p.empilha(10);String nome = (String) p.
desempilha();System.out.println("nome:"+nome);
}
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at TesteObjeto.main(TesteObjeto.java:12)
Mais um teste ...
public static void main(String[] args) {PilhaObjeto p = new PilhaObjeto (5);p.empilha("Joao");p.empilha("Jose");p.empilha(10);String nome = (String) p.
desempilha();System.out.println("nome:"+nome);
}
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at TesteObjeto.main(TesteObjeto.java:12)
Esperava este erro
public static void main(String[] args) {PilhaObjeto p = new PilhaObjeto (5);p.empilha("Joao");p.empilha("Jose");p.empilha(10);String nome = (String) p.
desempilha();System.out.println("nome:"+nome);
}
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at TesteObjeto.main(TesteObjeto.java:12)
Mas achava que estava armazenando um int. O que é este Integer?
Esta solução funciona apenas sobre objetos e não tipos
primitivos. O Integer é um objeto equivalente ao Int.
Além disso, similar ao usar *void em C, Object em Java pode gerar
problemas em tempo de execução. Devido a inconsistência
em operações.
DILEMA: Tipos garante consistência nas operações mas enrijece a definição dos meus
métodos. Como resolver?
Até 2004, antes da versão 1.5, teríamos que nos contentar com
o uso de Object.
Porem com a versão 1.5 o Java passou a suportar classes
genéricas, também conhecido como polimorfismo
paramétrico.
Ok. Vou pesquisar.....
Generics em Java é similar a templates
em C++.
Basicamente substituo tipos por
um T genérico.
public class PilhaGeneric <T> {T v[];int pos;public PilhaGeneric (int n) {
v = new T [n];pos = 0;
}public void empilha(T x) {
v[pos++] = x;}public T desempilha() {
return v[--pos] ;}
}
Não funcionou como esperado. Java não
reconheceu o construtor genérico
public class PilhaGeneric <T> {T v[];int pos;public PilhaGeneric (int n) {
v = new T [n];pos = 0;
}public void empilha(T x) {
v[pos++] = x;}public T desempilha() {
return v[--pos] ;}
}
Por que será ?
public class PilhaGeneric <T> {T v[];int pos;public PilhaGeneric (int n) {
v = new T [n];pos = 0;
}public void empilha(T x) {
v[pos++] = x;}public T desempilha() {
return v[--pos] ;}
}
Java utiliza um mecanismo chamado Erasure para gerar os
códigos finais.
public class PilhaGeneric <T> {T v[];int pos;public PilhaGeneric (int n) {
v = new T [n];pos = 0;
}public void empilha(T x) {
v[pos++] = x;}public T desempilha() {
return v[--pos] ;}
}
Por enquanto saiba que o Java não sabe
mapear um construtor T genérico.
public class PilhaGeneric <T> {T v[];int pos;@SuppressWarnings("unchecked")public PilhaGeneric (int n) {
v = (T[]) new Object [n];pos = 0;
}public void empilha(T x) {
v[pos++] = x;}public T desempilha() {
return v[--pos] ;}
}
Solução é construir Object[] e depois
fazer um Cast.
PilhaGeneric<Integer> p = new PilhaGeneric <Integer> (5);p.empilha(10);p.empilha("joao");
Agora podemos usar.
Causa um erro. A pilha é do tipo Integer. Mantem consistência.
Além do array nativo da linguagem Java, existem coleções.
Esta tua classe pilha poderia usar uma
coleção ao invés de um array.
public class PilhaGeneric2 <T> {private List<T> v; public PilhaGeneric2 () {
v = new ArrayList<T>();}public void empilha(T x) {
v.add(x);}public T desempilha() {
return v.remove(v.size()-1) ;}
}
Então poderíamos usar da seguinte
maneira.
PilhaGeneric2<Integer> p = new PilhaGeneric2 <Integer> ();
p.empilha(10);p.empilha(20);System.out.println(p.desempilha());System.out.println(p.desempilha());
E se sua pilha tivesse que retornar o maior
valor?
Fácil, não é só escrever o seguinte
método? O que acham?
public T maior () {T maior = v.get(0);for (int i=0; i< v.size(); i++) {
if (v.get(i) > maior)maior = v.get(i);
}return maior;
}
public T maior () {T maior = v.get(0);for (int i=0; i< v.size(); i++) {
if (v.get(i) > maior)maior = v.get(i);
}return maior;
}
Fácil, não é só escrever o seguinte
método? O que acham?
Será que o operador (>) pode ser aplicado em qualquer objeto?
Verdade, este método não é tão genérico. O objeto preciso saber
comparar.
public T maior () {T maior = v.get(0);for (int i=0; i< v.size(); i++) {
if (v.get(i) > maior)maior = v.get(i);
}return maior;
}
Em C++, basta eu sobrecarregar o
operador (>). E em Java?
public T maior () {T maior = v.get(0);for (int i=0; i< v.size(); i++) {
if (v.get(i) > maior)maior = v.get(i);
}return maior;
}
Java não possui sobrecarga de
operadores, somente de métodos.
Existe um método que equivale a
comparação: compareTo
Posso usar este método da seguinte
maneira
public T maior () {T maior = v.get(0);for (int i=0; i< v.size(); i++) {
if (v.get(i).compareTo(maior) > 0)
maior = v.get(i);}return maior;
}
Porém preciso dizer que a minha pilha funciona com qualquer T, desde que ele
“extenda” a classe Comparable
public class PilhaGeneric3 <T extends Comparable<T>> {
…}
A classe pilha ficaria da seguinte maneira
public class PilhaGeneric3 <T extends Comparable<T>> {
private List<T> v; public PilhaGeneric3 () {
v = new ArrayList<T>();}public void empilha(T x) {
v.add(x);}public T desempilha() {
return v.remove(v.size()-1) ;}
public T maior () {T maior = v.get(0);for (int i=0; i< v.size(); i++) {
if (v.get(i).compareTo(maior) > 0)
maior = v.get(i);}return maior;
}}
Na verdade, o Java provê um framework completo
para lidar com coleções de dados.
Entendi. Melhor aprender usar o
“framework collection”
Excelente apresentação sobre Collections e Generics
top related