我想根据谓词筛选java.util.Collection。
当前回答
考虑使用支持泛型的更新的Collections框架谷歌Collections。
更新:谷歌集合库现在已弃用。你应该使用最新发布的番石榴。它仍然具有对集合框架的所有相同扩展,包括基于谓词进行筛选的机制。
其他回答
我写了一个扩展的Iterable类,它支持在不复制集合内容的情况下应用函数式算法。
用法:
List<Integer> myList = new ArrayList<Integer>(){ 1, 2, 3, 4, 5 }
Iterable<Integer> filtered = Iterable.wrap(myList).select(new Predicate1<Integer>()
{
public Boolean call(Integer n) throws FunctionalException
{
return n % 2 == 0;
}
})
for( int n : filtered )
{
System.out.println(n);
}
上面的代码将实际执行
for( int n : myList )
{
if( n % 2 == 0 )
{
System.out.println(n);
}
}
这里有一些非常棒的答案。对我来说,我想让事情尽可能简单易懂:
public abstract class AbstractFilter<T> {
/**
* Method that returns whether an item is to be included or not.
* @param item an item from the given collection.
* @return true if this item is to be included in the collection, false in case it has to be removed.
*/
protected abstract boolean excludeItem(T item);
public void filter(Collection<T> collection) {
if (CollectionUtils.isNotEmpty(collection)) {
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
if (excludeItem(iterator.next())) {
iterator.remove();
}
}
}
}
}
您可以使用ForEach DSL编写
import static ch.akuhn.util.query.Query.select;
import static ch.akuhn.util.query.Query.$result;
import ch.akuhn.util.query.Select;
Collection<String> collection = ...
for (Select<String> each : select(collection)) {
each.yield = each.value.length() > 3;
}
Collection<String> result = $result();
给定一个集合[The, quick, brown, fox, jumping, over, The, lazy, dog],结果是[quick, brown, jumping, over, lazy],即所有字符串都长于三个字符。
ForEach DSL支持的所有迭代样式都是
AllSatisfy AnySatisfy 收集 Counnt CutPieces 检测 GroupedBy IndexOf InjectInto 拒绝 选择
更多详情请参考https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach
使用java 8,特别是lambda表达式,你可以像下面的例子那样简单:
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
其中,对于myProducts集合中的每个产品,如果prodc .price>10,则将该产品添加到新的过滤列表中。
“最好”这个要求太宽泛了。它是“最短的”吗?“最快”?“可读”? 过滤器的地方或到另一个集合?
最简单(但不是最易读)的方法是迭代它,并使用Iterator.remove()方法:
Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
Foo foo = it.next();
if( !condition(foo) ) it.remove();
}
现在,为了使其更具可读性,可以将其包装到实用程序方法中。然后发明一个IPredicate接口,创建该接口的匿名实现,并执行如下操作:
CollectionUtils.filterInPlace(col,
new IPredicate<Foo>(){
public boolean keepIt(Foo foo) {
return foo.isBar();
}
});
where filterInPlace()迭代集合并调用Predicate.keepIt()来了解实例是否保留在集合中。
我真的没有看到为这项任务引入第三方库的正当理由。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 如何检查IEnumerable是否为空或空?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder