Busca por objetos dentro de uma lista

7 respostas
L

Olá, criei uma lista com milhares de objetos de uma mesma classe, e agora preciso filtrar isso por algumas propriedades desta classe.
ex.:

class pessoas {
  nome
  datanascimento
  sexo
  cor
  religiao
  ...
}

Preciso separar (sem ficar percorrendo a lista toda), por exemplo todas as pessoas de determinada religião. Poderia resultar numa outra lista, ou algo que eu possa percorrer somente os objetos filtrados.

Seria bom algo do tipo:
iterator it = listaPessoas.findBy(religiao, 3) //onde 3 é a religião que estou buscando… :>

Obrigado!

7 Respostas

T

Essa é uma das deficiências do Java (não ser muito adequado para processamento de listas).
Que eu saiba, você vai ter de fazer isso “na mão” - percorrer todos os elementos e gerar uma nova lista, ou então criar uma classe que implementa a interface Iterator ou Iterable.
Se você sabe que a lista pode ser ordenada por algumas chaves, você pode tentar usar TreeMap ou HashMap.

L

Não precisa realmente ser uma lista, pode ser qualquer estrutura em java onde possa colocar objetos e depois recuperá-los de forma rápida…
Como eu poderia usar esses dois caras?

T

Você pode organizar uma coleção de objetos usando TreeMap ou HashMap.
Dada uma chave, você pode obter o valor. Por exemplo: "catolica" -&gt Pessoa ("Jose Aparecido", "catolica", "25/12/1990").
O problema de TreeMap e HashMap é que no seu caso muitos valores terão a mesma chave, e você precisaria fazer um TreeMap ou HashMap de listas de Pessoa, não de Pessoa.

Vou dar um exemplo completo.

iimport java.util.*;

class Pessoa {
    public String nome;
	public String religiao;
	public String endereco;
	public Pessoa (String nome, String religiao, String endereco) {
	    this.nome = nome;
		this.religiao = religiao;
		this.endereco = endereco;
	}
	public String toString() {
	    return " &lt nome=" + nome + ", religiao=" + religiao + ", endereco=" + endereco + " &gt ";
	}
}
public class ExemploMapa {
    private List &lt Pessoa &gt  pessoas;
    private Map &lt String, List &lt Pessoa &gt  &gt  pessoasPorReligiao;
    public void teste() {
	    pessoas = new ArrayList &lt Pessoa &gt ();
	    pessoas.add (new Pessoa ("Jose Aparecido", "catolica", "R. das Azaleas, 22"));
		pessoas.add (new Pessoa ("Takashi Abe", "budista", "R. das Betulas, 23"));
		pessoas.add (new Pessoa ("John Smith", "protestante", "R. dos Carvalhos, 25"));
		pessoas.add (new Pessoa ("Severino Cavalcanti", "catolica", "R. das Dracenas, 26"));
	    // Criando o mapa "pessoasPorReligiao"
		pessoasPorReligiao = new TreeMap &lt String, List &lt Pessoa &gt  &gt ();
		for (Pessoa pessoa : pessoas) {
		    List &lt Pessoa &gt  pessoasComMesmaReligiao;
		    if (!pessoasPorReligiao.containsKey (pessoa.religiao)) {
			    pessoasComMesmaReligiao = new ArrayList &lt Pessoa &gt ();
				pessoasPorReligiao.put (pessoa.religiao, pessoasComMesmaReligiao);
			} else {
			    pessoasComMesmaReligiao = pessoasPorReligiao.get (pessoa.religiao);
		    }
			pessoasComMesmaReligiao.add (pessoa);
		}
		// Agora vamos listar as pessoas com religião católica
		System.out.println (pessoasPorReligiao.get ("catolica"));
		// Vamos listar as pessoas com religião protestante
		System.out.println (pessoasPorReligiao.get ("protestante"));
	}
	public static void main (String[] args) {
        ExemploMapa mp = new ExemploMapa();
		mp.teste();
    }
}
L

Valeu pela dica. Sabe me dizer se o Hibernate faz algo parecido com isso ai?

sergiotaborda

larini:
Olá, criei uma lista com milhares de objetos de uma mesma classe, e agora preciso filtrar isso por algumas propriedades desta classe.
ex.:
(…)

Vc precia de um filtro

interface Filter {
 
      boolean accept(Object obj);

}

class FilterUtils{


       public static Collection filter (Collection col , Filter filter){

            Collection result = new ArrayList();

            for (Iterator it = col.iterator(); it.hasNext();){
                  Object obj = it.next();
                 if (filter.accept(obj)}
                    result.add(obj);
                }
            }

           return result;
       }

}

// uso 

Collection res = FilterUtils.filter(listaPessoas, new Filter(){

           public boolean accept(Object obj){
                return ((Pessoa)obj).getReligiao() == 3;
          }
});


// res contém pessoas cuja religiao é 3
L

Sergio, pelo que parece esse método vai percorrer toda a lista, algo que eu não posso fazer.

sergiotaborda

:lol: O método o Tingol tb precorre toda a lista e vc acho maravilhoso.
Cara, não tem como não precorrer toda a lista usando java puro e dada um lista pre-carregada!!!

A única forma de não precorrer toda a lista é trazendo do banco de dados a lista já filtrada ou pre-classificar os dados.Ao pre-classificar vc não usa um List, mas um objeto proprio que pre-classifique os dados de certa forma pre-definida como o tingol mostrou ( usando mapas de listas) mas fazendo isso no Add e não num for. Mas o problema da pre-classificação é que ela resolve os caso mais usados, não resolve todos os casos. É uma especie de cache dos casos mais comuns.

Criado 5 de setembro de 2007
Ultima resposta 5 de set. de 2007
Respostas 7
Participantes 3