Pesquisa em Collections ou Lists [RESOLVIDO]

Existe alguma forma facil de fazer uma pesquisa em Coleções ??

por exemplo… digamos que eu tenha uma lista de objetos “Carro” que contem diversas propriedades… e eu queira, filtrar de uma lista, os carros com KM acima de X, que tenham 4p, que sejam da montadora Y … conciderando que carro contem todas essas propriedades… há alguma forma facil de fazer essas pesquisas ?? com Collection ??

A unica forma é percorrendo toda a lista ? verificando cada propriedade, implementando os testes ?? imagino que aquele padrão Criterion possa funcionar bem pra isso… mais eu não peguei bem o esperito da coisa, e como implementar ele de forma facil =/

brigadao ai pela resposta sergio, ^^

Comparator

comparator não tem utilidade para o que quero… não estou tentando ordenar objetos, estou querendo filtrar

Opa, foi mal, juro que li que era pra classificar e não filtrar. Mas olha só, se sua app está acessando um BD, vc pode fazer isso direto via SQL

porque nao busca esta lista direto do banco?

Pode fazer uma solução google-like… Utilize uma árvore para armazenar cada atributo da classe Carro.

[quote=joaorafael]porque nao busca esta lista direto do banco?
[/quote]

Pq se não vou ficar cheio de instancias das mesmas coisas…

Por exemplo… o cara mostra a lista completa… ai eu tenho uma List com todos os objetos… ai o cara clica que so quer da chevrolet… ai la vai eu instanciar objetos que já estão instanciados em novos objetos, so pra atender isso… e assim por diante…

acho que ficaria melhor pra perfomance fazer pelos dados da memoria e não no banco de dados…

Banco de dados otimiza essas consultas tanto na hora da consulta quando no armazenamento dos dados para serem consultados.

Se vc estiver usando JPA ou um ORM qq, e se habilitar o Cache, não necessariamente vc estará criando novos objetos. Mas concordo com vc que se já está com toda a lista na memória, seria bom não acessar o banco, ainda mais se for para web. Mas realmente não sei de uma forma que não seja percorrendo a lista mesmo.

Estou usando Hibernate…

Acredito que a unica forma seja via For…

mesmo assim, eu imagino que melhor que fazer as consultas ao banco de dados, novamente e novamente, seria melhor pesquisar entre os objetos ja instanciados… caso os objetos instanciados sejam sempre os mesmos, talvez não seja necessario fazer busca em Collections…

Depois vou testar, fazendo consultas distintas e verificando via == …

Mesmo se forem iguais, ainda tem o fato do hibernate descer umas 30 camadas ate chegar o banco, que vai ser algo externo, consultar ele, e responder com resultados, acredito que uma for e etcs, seria melhor pra performance…

[quote=Lavieri]Existe alguma forma facil de fazer uma pesquisa em Coleções ??

por exemplo… digamos que eu tenha uma lista de objetos “Carro” que contem diversas propriedades… e eu queira, filtrar de uma lista, os carros com KM acima de X, que tenham 4p, que sejam da montadora Y … conciderando que carro contem todas essas propriedades… há alguma forma facil de fazer essas pesquisas ?? com Collection ??

A unica forma é percorrendo toda a lista ? verificando cada propriedade, implementando os testes ?? imagino que aquele padrão Criterion possa funcionar bem pra isso… mais eu não peguei bem o esperito da coisa, e como implementar ele de forma facil =/[/quote]

Para pesquisar uma coleção pura ( uma coleção na memoria com objectos) a opção mais simples é usar o padrão Filter.
este padrão é muito simples, mas a perfomance não é muito boa porque implica em interar todos os elementos da coleção (afinal, sem os iterar como saber se passam ou não no filtro ?)

O padrão é simples . cria-se uma interface Filter com o método

interface Filter<T> {

  public boolean match (T object):
}

e um método que faz a pesquisa

Este método recebe um colection e retira todos os elementos que não casam com o filtro. Esta opção é mais rápida que criar outra coleção. Criar outra coleção que é a copia da primeira , retirar os elementos que não casam e retornar essa coleção tb é uma opção, mas menos rápida.


public static <T>void filter ( Collection <T> candidates, Filter<T> filter ){

       for (Iterator it = candidates.iterator(); it.hasNext(); ){
                if (!filter.match(it.next()){
                       it.remove();
                }
      }
}

Agora, o filtro pode ser implementado como quiser, por exemplo

[code]Collection all = … // obtem

CollectionUtils.filter ( all , new Filter{

     public boolean match (Carro carro ){
           return carro.getPortasCount()==4 && carro.getKM() == 20;
     }

}[/code]

É claro que vc pode criar uma classe que implemente Filter e tenha os parametros costumizáveis

sergiotaborda, vc sabe dizer c é mais rapido fazer o filtro nas collections, ou fazer nova pesquisa no banco de dados ? via hibernate ? com os parametros de filtragem??

como ja resolvi o problema das listas, estou seguindo com a discução sobre a performance nesse outro post:
Performance, Banco de dados ou fors ??

[quote=Lavieri]sergiotaborda, vc sabe dizer c é mais rapido fazer o filtro nas collections, ou fazer nova pesquisa no banco de dados ? via hibernate ? com os parametros de filtragem??

como ja resolvi o problema das listas, estou seguindo com a discução sobre a performance nesse outro post:
Performance, Banco de dados ou fors ??

[/quote]

Eu não tinha entendido que estava falando do hibernate (/ banco de dados)

se vc está usando o Hibernate então faça a pesquisa pelo hibernate. Primeiro porque os dados podem ser alterados por outros processos, segundo pq o hibernate tem cache dos objectos (ele já faz a pesquisa na memoria de forma melhor).

Pesquisas diretas em coleções são apenas interessantes quando não ha banco envolvido ou a aplicação não tem processos concorrentes.