使用对象的字段过滤 ArrayList
Posted
技术标签:
【中文标题】使用对象的字段过滤 ArrayList【英文标题】:filtering an ArrayList using an object's field 【发布时间】: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")));
但此代码不起作用。
【问题讨论】:
怎么不工作?我敢打赌编译错误... @fge 因为我正在使用字符串进行过滤,我没有使用对象的字段进行过滤,但我不知道该怎么做。 您需要实现自己的Predicate
,Predicates
提供的那些(notNull()
/isNull()
除外)都无法以有意义的方式过滤您的对象。你读过Functional explained吗?
我对 Guava 库并不熟悉,但我认为您需要使用 Predicate.compose(Predicate predicate, Function function)创建一个新函数来测试特定字段是否正确。我将在几分钟内发布一个带有某种确切解决方案的答案。但据我了解,这是你应该做的。
【参考方案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() 在 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 所展示的那样,这是相当多的代码,可以使用非函数式编程在更少的代码中完成......
【讨论】:
这里的列表是什么? @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表达式将不胜感激:)以上是关于使用对象的字段过滤 ArrayList的主要内容,如果未能解决你的问题,请参考以下文章
如何使用附加过滤的相关对象作为 Django 中的字段来获取结果?
如何使用 PHP 从 Google Clas-s-room 课程列表中过滤课程对象字段
Django-create 过滤器基于使用 Q 对象和 if elif 条件的每个字段