【问题标题】:filtering an ArrayList using an object's field使用对象的字段过滤 ArrayList
【发布时间】:2013-05-27 05:33:53
【问题描述】:

我有一个由对象填充的 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 字段过滤我的列表,而对于测试,我使用了字符串“test”。

我使用了谷歌的 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")));

但此代码不起作用。

【问题讨论】:

标签: java arraylist filtering guava


【解决方案1】:

您可以使用 for 循环或 for each 循环遍历列表。 您想根据某些条件创建另一个列表吗? 我认为这应该可行。

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

【讨论】:

    【解决方案2】:

    这是正常的:Predicates.containsPattern()CharSequences 上运行,而您的 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 所展示的那样,这是相当多的代码,可以使用非函数式编程在更少的代码中完成......

    【讨论】:

    • 这里的列表是什么?
    • @LahiruPrasanna 这是番石榴的Lists,因为问题是关于番石榴的
    【解决方案3】:

    试试这个:

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

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

    【讨论】:

      【解决方案4】:

      Guava 是一个库,可让您在 Java 中使用一些函数式编程。 函数式编程中最成功的事情之一是集合转换,例如

      集合 -> 操作 -> 操作 -> 操作 -> 转换集合。

      看这里:

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

      如果您的过滤条件需要正则表达式,代码会变得更加复杂,您需要将条件移动到单独的方法或将整个 Predicate 移动到单独的类。

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

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

      【讨论】:

      • 并不复杂,只是被混淆了。
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        在 Java 8 中,使用过滤器

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

        【讨论】:

        • 不使用lamda表达式将不胜感激:)
        猜你喜欢
        • 1970-01-01
        • 2011-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        相关资源
        最近更新 更多