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:



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

Popular posts from this blog

Telemetry and Microservices part2

Installing and Running ntop 2 on Amazon Linux OS

Fun with Apache Kafka