Java - Introdução a Coleções e Generics
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 1,034 views

 

Statistics

Views

Total Views
1,034
Views on SlideShare
972
Embed Views
62

Actions

Likes
0
Downloads
24
Comments
0

3 Embeds 62

https://mj89sp3sau2k7lj1eg3k40hkeppguj6j-a-sites-opensocial.googleusercontent.com 47
http://plus.url.google.com 8
https://twitter.com 7

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Java - Introdução a Coleções e Generics Java - Introdução a Coleções e Generics Presentation 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 ☺
  • 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 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] ; } }
  • 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()); } }
  • 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.
  • 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] ; } }
  • 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); }
  • 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); }
  • 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? 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)
  • 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.
  • 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; public PilhaGeneric (int n) { v = new T [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. 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] ; } }
  • 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.
  • 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; }
  • 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; }
  • 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