我有一个由对象填充的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”。
我使用了 google 的 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 8中,使用过滤器
List<Article> articleList = new ArrayList<Article>();
List<Article> filteredArticleList= articleList.stream().filter(article -> article.getDesArt().contains("test")).collect(Collectors.toList());
这是正常的:Predicates.containsPattern() 在
CharSequence
上运行,而您的 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 所示...
您可以使用 for 循环或 foreach 循环来循环遍历列表。 您想根据某些条件创建另一个列表吗? 我认为这应该有效。
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);
}
}
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 转换为即时创建的谓词:
Collection<Article> filtered = from(listArticles)
.filter(new Predicate<Article>() {
@Override
public boolean apply(Article candidate) {
return candidate.getCodeArt() > SOME_VALUE;
}
})
.toImmutableList();
如果您的过滤条件需要正则表达式,则代码会变得更加复杂,您将需要将条件移动到单独的方法或将整个谓词移动到单独的类。
如果所有这些函数式编程看起来太复杂,只需创建新集合并手动填充它(不使用 Guava):
List<Article> filtered = new ArrayList<Article>();
for(Article article : listArticles)
{
if(article.getCodeArt() > SOME_VALUE)
filtered.add(article);
}
对于 Guava,我想说迄今为止最简单的方法是使用 Collections2.filter,例如:
Collections2.filter(YOUR_COLLECTION, new Predicate<YOUR_OBJECT>() {
@Override
public boolean apply(YOUR_OBJECT candidate) {
return SOME_ATTRIBUTE.equals(candidate.getAttribute());
}
});
试试这个:
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")
}
}));
这个想法是因为您使用的是自定义对象,所以您应该实现自己的谓词。如果您在其他地方使用它,请在文件中定义它,否则,此实现可以很好地工作。
Try this :
// For new filter list
val filtered: ArrayList<Article> = ArrayList<Article>()
//mainList is original list from which filter out items basis on condition
mainList.filter{(it.desArt.lowercase().startsWith(query.lowercase())) }
.onEach { it1-> filtered.add(it1) }