使用对象的字段过滤ArrayList

时间:2013-05-31 11:46:51

标签: java arraylist filtering guava

我有一个由Objects填充的ArrayList。

我的对象类名为Article,它有两个字段;

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

}

我想使用desArt字段过滤我的列表,对于测试,我使用字符串"测试"。

我使用谷歌的Guava,它允许我过滤一个ArrayList。

这是我尝试过的代码:

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

但此代码无效。

6 个答案:

答案 0 :(得分:23)

在Java 8中,使用过滤器

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

答案 1 :(得分:16)

这是正常的:Predicates.containsPattern()CharSequence s上运行,gestionStock.Article对象未实现。

你需要编写自己的谓词:

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

然后使用:

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

然而,这是一些代码,可以使用非函数编程以更少的代码完成,如@mgnyp所示......

答案 2 :(得分:11)

您可以使用for循环或每个循环通过列表循环。 您想根据某些条件创建另一个列表吗? 这应该是我认为的。

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

答案 3 :(得分:2)

Guava是一个允许您在Java中使用某些函数式编程的库。 函数式编程中的一个成功之处是像

这样的集合转换

收藏 - &gt; op - &gt; op - &gt; op - &gt; transformedCollection。

看这里:

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

很漂亮,不是吗?

第二个获胜的东西是lambda函数。看这里:

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

实际上,Java还没有纯粹的lambda函数。我们将能够在Java 8中完成它。但是现在我们可以在IDE Inellij Idea中编写它,IDE将这样的lambda转换为Predicate,即时创建:

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

如果您的过滤条件需要regexp,则代码会变得更复杂,您需要将条件移动到单独的方法或将整个谓词移动到单独的类中。

如果所有这些函数式编程看起来太复杂,只需创建新的集合并手动填充它(没有Guava):

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

答案 4 :(得分:2)

对于Guava,我想说到目前为止最简单的方法是使用Collections2.filter,例如:

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

答案 5 :(得分:1)

试试这个:

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

这个想法是因为你正在使用自定义对象,你应该实现自己的谓词。如果您在其他任何地方使用它,请在文件中定义它,否则,此实现可以很好地工作。