java - introdução a coleções e generics

49
Java - Introdução a Coleções e Generics Prof. Sérgio Souza Costa

Upload: sergio-souza-costa

Post on 26-May-2015

868 views

Category:

Documents


3 download

TRANSCRIPT

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

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

Prof. Sérgio Souza Costa

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

Objetivo

• Prepararmos para entendermos como funciona o “framework collection” do Java.

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

Capítulo de hoje: Um programador C/C++ precisa lidar com coleções de dados em Java.

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

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 ☺

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

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

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

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 ....

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

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 ?

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

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?

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

Para aulas de estrutura de dados está ok, mas esta tua pilha não é muito útil. Ela é restrita a um tipo de dado (

inteiro)

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

Sim. Isso é por que Java é uma linguagem que os métodos e variáveis tem que ter tipos

definido estaticamente.

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

Em C, eu usava *void para estruturas genéricas. Depois

bastava eu fazer um cast para um tipo específico.

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

Será que Java não tem algo similar ? O que

vocês acham ?

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

Yes. Como toda classe em Java herda de

Object, este poderia ser o tipo da minha pilha.

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

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

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

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 ?

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

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 ...

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

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 ...

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

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

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

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?

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

Esta solução funciona apenas sobre objetos e não tipos

primitivos. O Integer é um objeto equivalente ao Int.

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

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.

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

DILEMA: Tipos garante consistência nas operações mas enrijece a definição dos meus

métodos. Como resolver?

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

Até 2004, antes da versão 1.5, teríamos que nos contentar com

o uso de Object.

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

Porem com a versão 1.5 o Java passou a suportar classes

genéricas, também conhecido como polimorfismo

paramétrico.

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

Ok. Vou pesquisar.....

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

Generics em Java é similar a templates

em C++.

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

Basicamente substituo tipos por

um T genérico.

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

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

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

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á ?

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

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.

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

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.

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

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.

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

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.

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

Além do array nativo da linguagem Java, existem coleções.

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

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) ;}

}

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

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());

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

E se sua pilha tivesse que retornar o maior

valor?

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

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;

}

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

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?

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

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;

}

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

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;

}

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

Java não possui sobrecarga de

operadores, somente de métodos.

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

Existe um método que equivale a

comparação: compareTo

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

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;

}

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

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>> {

…}

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

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;

}}

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

Na verdade, o Java provê um framework completo

para lidar com coleções de dados.

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

Entendi. Melhor aprender usar o

“framework collection”