Comment rechercher des éléments par critères en java.Util.Liste?


Par exemple:

J'ai une table comme celle-ci du côté de l'interface utilisateur:

entrez la description de l'image ici

Et c'est la liste qui a toutes les données montrées ci-dessus:

List<MyBean> myList;

Maintenant, je veux rechercher par categoryName, languageID ou categoryID en utilisant une méthode comme celle-ci:

private List<MyBean> search(List<MyBean> myList, String columnName, String criteria)

Alors je fais ce qui suit pour obtenir les résultats qui correspondent à mes critères:

1er cas: List<Bean> results = this.search(myList, "categoryName", "Dog H");

2ème cas: List<Bean> results = this.search(myList, "categoryName", "Dog House");

(À ce stade, results list retourne 3 éléments dans les deux cas according selon le tableau ci-dessus).


Est-il possible de réaliser cela? Comme vous pouvez le voir, il s'agit d'une sorte de recherche similaire à la fonction %LIKE% de SQL mais axée sur java.util.List

Merci d'avance.

Author: Oscar Jara, 2012-08-07

4 answers

J'ai résolu ma question en utilisant ce qui suit:

Ensuite, je viens d'importer l'espace de noms suivant de cette façon:

import static ch.lambdaj.Lambda.*;

Et obtenir les résultats de mes critères en utilisant ceci:

List<MyBean> results = select(myList, having(on(MyBean.class).getCategoryName(), org.hamcrest.Matchers.containsString("Dog H")));

Donc, dans cette ligne de code, je passe myList, le "column" et criteria comme je l'ai demandé dans ma question.

Le reste du code sur cette ligne est facile à comprendre, donc je n'écrirai pas à ce sujet.

J'espère que cela aidera quelqu'un d'autre aussi.

 6
Author: Oscar Jara, 2014-08-27 12:39:14

Voici deux approches

L'approche "énergique";)

public List<MyBean> search(List<MyBean> lstBeans, String method, String regExp) {
    List<MyBean> lstMatch = new ArrayList<>(lstBeans.size());
    Pattern pattern = Pattern.compile(regExp);
    for (MyBean bean : lstBeans) {

        if (method.equals("categoryName")) {
            String name = bean.getCategoryName();
            if (pattern.matcher(name).matches()) {
                lstMatch.add(bean);
            }
        }
    }
    return lstMatch;
}

.
.
.

List<MyBean> matches = search(lstBeans, "categoryName", "^Dog.*$");

Fondamentalement, cela repose sur le fait de savoir qu'un nom de méthode donné retournera un résultat donné, ce qui rendrait difficile le filtrage des résultats sur la catégorie, par exemple...

Il y a aussi des problèmes avec les gens qui orthographient mal le nom de la méthode ou qui ne tiennent pas compte du fait qu'il est sensible à la casse...

OU vous pouvez essayer quelque chose d'un peu plus variable

public interface Criteria<T> {
    public boolean matches(T bean);
}

public class CategoryNameCriteria implements Criteria<MyBean> {

    private Pattern pattern;

    public CategoryCriteria(String criteria) {
        pattern = Pattern.compile(criteria);
    }

    @Override
    public boolean matches(MyBean bean) {
        return pattern.matcher(bean.getCategoryName()).matches();
    }

}

public <T> List<T> search(List<T> lstBeans, Criteria<T> critera) {
    List<T> lstMatch = new ArrayList<>(lstBeans.size());
    for (T bean : lstBeans) {
        if (critera.matches(bean)) {
            lstMatch.add(bean);
        }
    }
    return lstMatch;
}

.
.
.

matches = search(lstBeans, new CategoryNameCriteria("^Dog.*$"));

Cela vous permettrait de définir vos propres critères et exigences correspondant sans changer la méthode de base

Cela signifie que vous pourriez élaborer une série de critères indépendants de la méthode de recherche, tels que

public class CategoryIDCriteria implements Criteria<MyBean> {

    private int id;

    public CategoryIDCriteria(int id) {
        this.id = id;
    }

    @Override
    public boolean matches(MyBean bean) {
        return bean.getCategoryID() == id;
    }

}

.
.
.

matches = search(lstBeans, new CategoryIDCriteria(1));

Et parce que les critères et la méthode de recherche sont génériques, il serait possible de le réutiliser avec différents types d'objets

 3
Author: MadProgrammer, 2012-08-07 04:37:18

Si vous êtes prêt à utiliser des bibliothèques tierces, peut-être JoSQL suffira? Il vous permet de filtrer les collections de POJO à l'aide de requêtes SQL...

De plus, si vous êtes prêt à vous éloigner des requêtes SQL, cet ancien article peut être intéressant: Comment interrogez-vous les collections d'objets en Java (Criteria/SQL-like)?

 2
Author: Dilum Ranatunga, 2017-05-23 12:17:44

Au lieu d'une liste, pourquoi ne pas utiliser la table de Goyave?

Table<Integer, Integer, String> table = HashBasedTable.create(); 
table.put(1, 1, "Advantage Flea");
table.put(1, 2, "Advantage Flea");
table.put(1, 3, "Advantage Flea");
.
.
.

Case # 1 nécessite quelque chose comme:

Collection<String> values = table.values();
for(String value : values) { 
   if(value.contains(queryString) { 
       //found it!
   }
}

Case # 2 est trivial, et ressemble juste à:

if(table.containsValue("Advantage Flea") { 
    ...
}
 0
Author: Amir Afghani, 2012-08-07 04:49:19