Java - Introdução a Coleções e Generics

1,023
-1

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,023
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
57
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Java - Introdução a Coleções e Generics

  1. 1. Java - Introdução a Coleções e Generics Prof. Sérgio Souza Costa
  2. 2. Objetivo • Prepararmos para entendermos como funciona o “framework collection” do Java.
  3. 3. Capítulo de hoje: Um programador C/C++ precisa lidar com coleções de dados em Java.
  4. 4. 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 ☺
  5. 5. 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] ; } }
  6. 6. 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] ; } }
  7. 7. Ok. Falta fazer uns testes, mas .... Quais testes ele está se referindo ? 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] ; } }
  8. 8. Testando minha pilha. O que acharam? 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()); } }
  9. 9. Para aulas de estrutura de dados está ok, mas esta tua pilha não é muito útil. Ela é restrita a um tipo de dado ( inteiro)
  10. 10. Sim. Isso é por que Java é uma linguagem que os métodos e variáveis tem que ter tipos definido estaticamente.
  11. 11. Em C, eu usava *void para estruturas genéricas. Depois bastava eu fazer um cast para um tipo específico.
  12. 12. Será que Java não tem algo similar ? O que vocês acham ?
  13. 13. Yes. Como toda classe em Java herda de Object, este poderia ser o tipo da minha pilha.
  14. 14. Pilha de Object 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] ; } }
  15. 15. Resolvido. O que acharam ? 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); }
  16. 16. 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); }
  17. 17. 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)
  18. 18. 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)
  19. 19. Mas achava que estava armazenando um int. O que é este Integer? 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)
  20. 20. Esta solução funciona apenas sobre objetos e não tipos primitivos. O Integer é um objeto equivalente ao Int.
  21. 21. 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.
  22. 22. DILEMA: Tipos garante consistência nas operações mas enrijece a definição dos meus métodos. Como resolver?
  23. 23. Até 2004, antes da versão 1.5, teríamos que nos contentar com o uso de Object.
  24. 24. Porem com a versão 1.5 o Java passou a suportar classes genéricas, também conhecido como polimorfismo paramétrico.
  25. 25. Ok. Vou pesquisar.....
  26. 26. Generics em Java é similar a templates em C++.
  27. 27. Basicamente substituo tipos por um T genérico.
  28. 28. 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] ; } }
  29. 29. 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] ; } }
  30. 30. 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] ; } }
  31. 31. Por enquanto saiba que o Java não sabe mapear um construtor 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] ; } }
  32. 32. Solução é construir Object[] e depois fazer um Cast. 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] ; } }
  33. 33. Agora podemos usar. PilhaGeneric<Integer> p = new PilhaGeneric <Integer> (5); p.empilha(10); p.empilha("joao"); Causa um erro. A pilha é do tipo Integer. Mantem consistência.
  34. 34. Além do array nativo da linguagem Java, existem coleções.
  35. 35. 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) ; } }
  36. 36. 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());
  37. 37. E se sua pilha tivesse que retornar o maior valor?
  38. 38. 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; }
  39. 39. Fácil, não é só escrever o seguinte método? O que acham? Será que o operador (>) pode ser aplicado em qualquer objeto? 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; }
  40. 40. 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; }
  41. 41. 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; }
  42. 42. Java não possui sobrecarga de operadores, somente de métodos.
  43. 43. Existe um método que equivale a comparação: compareTo
  44. 44. 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; }
  45. 45. 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>> { … }
  46. 46. 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; } }
  47. 47. Na verdade, o Java provê um framework completo para lidar com coleções de dados.
  48. 48. Entendi. Melhor aprender usar o “framework collection”
  49. 49. Excelente apresentação sobre Collections e Generics

×