web-dev-qa-db-fra.com

filtrer une ArrayList à l'aide du champ d'un objet

J'ai une ArrayList qui est remplie par des objets.

Ma classe d'objets appelée Article qui a deux champs;

public class Article {

    private int codeArt;
    private String desArt;

  public Article(int aInt, String string) {
        this.desArt = string;
        this.codeArt = aInt;
    }

    public int getCodeArt() {return codeArt; }
    public void setCodeArt(int codeArt) {this.codeArt = codeArt;}
    public String getDesArt() {return desArt;}
    public void setDesArt(String desArt) { this.desArt = desArt;}

}

Je veux filtrer ma liste en utilisant le champ desArt, et pour le test j'ai utilisé la chaîne "test".

J'ai utilisé la goyave de Google qui me permet de filtrer une liste de tableaux.

c'est le code que j'ai essayé:

private List<gestionstock.Article> listArticles = new ArrayList<>();

//Here the I've filled my ArrayList

private List<gestionstock.Article> filteredList filteredList = Lists.newArrayList(Collections2.filter(listArticles, Predicates.containsPattern("test")));

mais ce code ne fonctionne pas.

13
Aimad Majdou

C'est normal: Predicates.containsPattern () fonctionne sur CharSequences, que votre gestionStock.Article l'objet n'est pas implémenté.

Vous devez écrire votre propre prédicat:

public final class ArticleFilter
    implements Predicate<gestionstock.Article>
{
    private final Pattern pattern;

    public ArticleFilter(final String regex)
    {
        pattern = Pattern.compile(regex);
    }

    @Override
    public boolean apply(final gestionstock.Article input)
    {
        return pattern.matcher(input.getDesArt()).find();
    }
}

Utilisez ensuite:

 private List<gestionstock.Article> filteredList
     = Lists.newArrayList(Collections2.filter(listArticles,     
         new ArticleFilter("test")));

Cependant, c'est un peu de code pour quelque chose qui peut être fait en beaucoup moins de code en utilisant une programmation non fonctionnelle, comme l'a démontré @mgnyp ...

17
fge

Dans Java 8, en utilisant un filtre

List<Article> articleList = new ArrayList<Article>();
List<Article> filteredArticleList= articleList.stream().filter(article -> article.getDesArt().contains("test")).collect(Collectors.toList());
24
Free-Minded

Vous pouvez utiliser une boucle for ou chaque boucle pour parcourir la liste. Voulez-vous créer une autre liste basée sur une condition? Cela devrait fonctionner, je pense.

List<Article> secondList = new ArrayList<Article>();

for( Article a : listArticles) { 
// or equalsIgnoreCase or whatever your conditon is
if (a.getDesArt().equals("some String")) {
// do something 
secondList.add(a);
}
}
11
monika

Guava est une bibliothèque qui vous permet d'utiliser une programmation fonctionnelle en Java. L'une des choses gagnantes dans la programmation fonctionnelle est la transformation de la collection comme

Collection -> op -> op -> op -> transformerCollection.

Regardez ici:

Collection<Article> filtered = from(listArticles).filter(myPredicate1).filter(myPredicate2).filter(myPredicate3).toImmutableList();

C'est beau, non?

La deuxième chose gagnante est les fonctions lambda. Regardez ici:

Collection<Article> filtered = from(listArticles)
  .filter((Predicate) (candidate) -> { return candidate.getCodeArt() > SOME_VALUE })
  .toImmutableList();

En fait, Java n'a pas encore de fonctions lambda pures. Nous pourrons le faire en Java 8. Mais pour l'instant, nous pouvons l'écrire en IDE Inellij Idea, et IDE transforme un tel lambda en prédicat, créé à la volée:

Collection<Article> filtered = from(listArticles)
        .filter(new Predicate<Article>() {
            @Override
            public boolean apply(Article candidate) {
                return candidate.getCodeArt() > SOME_VALUE;
            }
        })
        .toImmutableList();

Si votre condition de filtre nécessite une expression rationnelle, le code devient plus compliqué et vous devrez déplacer la condition vers une méthode distincte ou déplacer le prédicat entier vers une classe distincte.

Si toute cette programmation fonctionnelle vous semble trop compliquée, créez simplement une nouvelle collection et remplissez-la manuellement (sans Guava):

List<Article> filtered = new ArrayList<Article>();
for(Article article : listArticles)
{
    if(article.getCodeArt() > SOME_VALUE)
        filtered.add(article);
}
2
n00bot

Avec Guava, je dirais que le moyen le plus simple serait de loin d'utiliser Collections2.filter, comme:

Collections2.filter(YOUR_COLLECTION, new Predicate<YOUR_OBJECT>() {
  @Override
  public boolean apply(YOUR_OBJECT candidate) {
    return SOME_ATTRIBUTE.equals(candidate.getAttribute());
  }
});
2
facundofarias

Essaye ça:

private List<gestionstock.Article> listArticles = new ArrayList<>();
private List<gestionstock.Article> filteredList filteredList = Lists.newArrayList(Collections2.filter(listArticles, new Predicate<gestionstock.Article>(){
        public boolean apply(gestationstock.Article article){
            return article.getDesArt().contains("test")
        }
    }));

L'idée étant que vous utilisez un objet personnalisé, vous devez implémenter votre propre prédicat. Si vous l'utilisez ailleurs, définissez-le dans un fichier, sinon, cette implémentation fonctionne bien.

1
user1732480