Aimad Majdou
Aimad Majdou

Reputation: 583

filtering an ArrayList using an object's field

I have an ArrayList which is filled by Objects.

My object class called Article which has two fields ;

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;}

}

I want to filter my List using the desArt field, and for test I used the String "test".

I used the Guava from google which allows me to filter an ArrayList.

this is the code I tried :

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")));

but this code isn't working.

Upvotes: 25

Views: 103145

Answers (7)

CA Tawde
CA Tawde

Reputation: 1

Try This : 
// For new filter list
val filtered: ArrayList<Article> = ArrayList<Article>()

//mainList is original list from which filter out items basis on condition
// use startswith/contains etc as per requirement
// below "query" used for search text related

mainList.filter{(it.desArt.lowercase().startsWith(query.lowercase())) }
.onEach { it1-> filtered.add(it1) }

Upvotes: 0

Free-Minded
Free-Minded

Reputation: 5430

In Java 8, using filter

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

Upvotes: 41

facundofarias
facundofarias

Reputation: 3043

With Guava, I would say that the easiest way by far would be by using Collections2.filter, such as:

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

Upvotes: 3

fge
fge

Reputation: 121710

This is normal: Predicates.containsPattern() operates on CharSequences, which your gestionStock.Article object does not implement.

You need to write your own predicate:

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();
    }
}

Then use:

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

However, this is quite some code for something which can be done in much less code using non functional programming, as demonstrated by @mgnyp...

Upvotes: 19

n00bot
n00bot

Reputation: 229

Guava is a library that allows you to use some functional programming in Java. One of the winning things in functional programming is collection transformation like

Collection -> op -> op -> op -> transformedCollection.

Look here:

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

It's beautiful, isn't it?

The second one winning thing is lambda functions. Look here:

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

Actually, Java has not pure lambda functions yet. We will be able to do it in Java 8. But for now we can write this in IDE Inellij Idea, and IDE transforms such lambda into Predicate, created on-the-fly:

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

If your filter condition requires regexp, the code become more complicated, and you will need to move condition to separate method or move whole Predicate to a separate class.

If all this functional programming seems too complicated, just create new collection and fill it manually (without Guava):

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

Upvotes: 3

user1732480
user1732480

Reputation:

Try this:

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")
        }
    }));

The idea being is since you're using a custom object, you should implement your own predicate. If you're using it anywhere else, define it in a file, otherwise, this implementation works nicely.

Upvotes: 0

monika
monika

Reputation: 499

You can use a for loop or for each loop to loop thru the list. Do you want to create another list based on some condition? This should work I think.

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);
}
}

Upvotes: 16

Related Questions