For-each java 5.0: Topicos Avançados
Uma das mais importantes novidades do java é o for-each, com ele podemos iterar Collections e Arrays de forma mais limpa e com menos código. Antigamente tinha que fazer algo assim:
Já no java 5.0 podemos fazer:
Mas com o novo for-each podemos percorrer qualquer coisa, basta que a classe implemente java.lang.Iterable ou um método retornar um Iterator. No exemplo a seguir mostro como iterar de maneira lazy um conjunto de pojos Pessoa que foram persistidas no disco através de Serialização.
Pessoa.java
PessoaDao.java
PessoaReader.java
TestForeach.java
Interessante não? Como isso podemos fazer com que praticamente qualquer estrutura posse ser percorida pelo for-each e como lazy.
Crom...
List l = new ArrayList();
l.add(new Integer(1));
l.add(new Integer(2));
l.add(new Integer(3));
for(Iterator it=l.iterator;it.hasNext();){
System.out.println(((Integer)it.next()).intValue())
}
Já no java 5.0 podemos fazer:
List<Integer> l = new ArrayList<Integer>();
l.add(1);
l.add(2);
l.add(3);
for(Integer i: l){
System.out.println(i);
}
Mas com o novo for-each podemos percorrer qualquer coisa, basta que a classe implemente java.lang.Iterable ou um método retornar um Iterator. No exemplo a seguir mostro como iterar de maneira lazy um conjunto de pojos Pessoa que foram persistidas no disco através de Serialização.
Pessoa.java
package org.diegopacheco.javaforeach.model;
import java.io.Serializable;
/**
* Pojo que representa uma pessoa.
* @author Diego Pacheco
*
*/
public class Pessoa implements Serializable{
private static final long serialVersionUID = 1L;
private String nome;
private Integer idade;
public Pessoa() {}
public Pessoa(String nome, Integer idade) {
super();
this.nome = nome;
this.idade = idade;
}
public Integer getIdade() {
return idade;
}
public void setIdade(Integer idade) {
this.idade = idade;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
@Override
public String toString() {
return "Nome: " + nome + ", idade: " + idade;
}
}
PessoaDao.java
package org.diegopacheco.javaforeach.model.dao;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.diegopacheco.javaforeach.model.Pessoa;
/**
* Classe DAO, que serializa 10 pessoas no file system.
* @author Diego Pacheco
*
*/
public class PessoaDao {
public void store(String pathFS){
List<Pessoa> pessoas = new ArrayList<Pessoa>();
for(int i=0;i<=10;i++){
pessoas.add(new Pessoa("pessoa" + i,i*5));
}
try{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(pathFS));
for(Pessoa p: pessoas){
oos.writeObject(p);
}
oos.flush();
oos.close();
}catch(Throwable t){
throw new RuntimeException("Erro ao serializar as pessoas. Message: " + t.getMessage());
}
System.out.println("Pessoas Persistidas com sucesso");
}
}
PessoaReader.java
package org.diegopacheco.javaforeach.util;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Iterator;
import org.diegopacheco.javaforeach.model.Pessoa;
/**
* Classe que é apta a ler pessoas do disco, que num processo
* previo foi serializada. E Assim ler isso de maneira Lazy e
* apta a ser percorida pelo for-each.
*
* @author Diego Pacheco
*
*/
public class PessoaReader implements Iterable{
private static ObjectInputStream ois;
public PessoaReader(String pathFS) {
try {
ois = new ObjectInputStream(new FileInputStream(pathFS));
} catch (Throwable t) {
throw new RuntimeException("Erro ao ler as pessoas. Message: " + t.getMessage());
}
}
public Iterator<Pessoa> iterator() {
return new Iterator<Pessoa>(){
private Pessoa pessoaHolder;
public boolean hasNext() {
Object aux;
try {
aux = ois.readObject();
}catch(EOFException e){
return false;
}catch (Throwable t) {
throw new RuntimeException("Erro ao ler pessoa. Message: " + t.getMessage());
}
pessoaHolder = (Pessoa) aux;
return true;
}
public Pessoa next() {
return pessoaHolder;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
protected void finalize() throws Throwable {
if (ois!=null) ois.close();
}
}
TestForeach.java
package org.diegopacheco.javaforeach.test;
import org.diegopacheco.javaforeach.model.Pessoa;
import org.diegopacheco.javaforeach.model.dao.PessoaDao;
import org.diegopacheco.javaforeach.util.PessoaReader;
/**
* Classe que exemplifica o uso e faz testes.
* @author Diego Pacheco
*
*/
public class TestForeach {
private static final String DATA = "C:/pessoas.ser";
public static void main(String[] args) {
// salva 10 pessoas(Serializa);
PessoaDao dao = new PessoaDao();
dao.store(DATA);
// pega um leiotr apto para ser usado com for-each.
PessoaReader pr = new PessoaReader(DATA);
for(Pessoa p: pr){
System.out.println(p);
}
}
}
Interessante não? Como isso podemos fazer com que praticamente qualquer estrutura posse ser percorida pelo for-each e como lazy.
Crom...