我想根据谓词筛选java.util.Collection。
当前回答
JFilter http://code.google.com/p/jfilter/最适合您的需求。
JFilter是一个简单、高性能的开源库,用于查询Java bean集合。
关键特性
Support of collection (java.util.Collection, java.util.Map and Array) properties. Support of collection inside collection of any depth. Support of inner queries. Support of parameterized queries. Can filter 1 million records in few 100 ms. Filter ( query) is given in simple json format, it is like Mangodb queries. Following are some examples. { "id":{"$le":"10"} where object id property is less than equals to 10. { "id": {"$in":["0", "100"]}} where object id property is 0 or 100. {"lineItems":{"lineAmount":"1"}} where lineItems collection property of parameterized type has lineAmount equals to 1. { "$and":[{"id": "0"}, {"billingAddress":{"city":"DEL"}}]} where id property is 0 and billingAddress.city property is DEL. {"lineItems":{"taxes":{ "key":{"code":"GST"}, "value":{"$gt": "1.01"}}}} where lineItems collection property of parameterized type which has taxes map type property of parameteriszed type has code equals to GST value greater than 1.01. {'$or':[{'code':'10'},{'skus': {'$and':[{'price':{'$in':['20', '40']}}, {'code':'RedApple'}]}}]} Select all products where product code is 10 or sku price in 20 and 40 and sku code is "RedApple".
其他回答
“最好”这个要求太宽泛了。它是“最短的”吗?“最快”?“可读”? 过滤器的地方或到另一个集合?
最简单(但不是最易读)的方法是迭代它,并使用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代码怎么样
List<Customer> list ...;
List<Customer> newList = new ArrayList<>();
for (Customer c : list){
if (c.getName().equals("dd")) newList.add(c);
}
简单、易读、简单(在Android上也适用!) 但如果你使用的是Java 8,你可以用一句简单的话来实现:
List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());
注意,toList()是静态导入的
使用java 8,特别是lambda表达式,你可以像下面的例子那样简单:
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
其中,对于myProducts集合中的每个产品,如果prodc .price>10,则将该产品添加到新的过滤列表中。
考虑使用支持泛型的更新的Collections框架谷歌Collections。
更新:谷歌集合库现在已弃用。你应该使用最新发布的番石榴。它仍然具有对集合框架的所有相同扩展,包括基于谓词进行筛选的机制。
https://code.google.com/p/joquery/
支持不同的可能性,
给定的集合,
Collection<Dto> testList = new ArrayList<>();
的类型,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
过滤器
Java 7
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property("id").eq().value(1);
Collection<Dto> filtered = query.list();
Java 8
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property(Dto::getId)
.eq().value(1);
Collection<Dto> filtered = query.list();
同时,
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.property(Dto::getId).between().value(1).value(2)
.and()
.property(Dto::grtText).in().value(new string[]{"a","b"});
排序(也可用于Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
分组(也可用于Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
连接(也可用于Java 7)
考虑到,
class LeftDto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
class RightDto
{
private int id;
private int leftId;
private String text;
public int getId()
{
return id;
}
public int getLeftId()
{
return leftId;
}
public int getText()
{
return text;
}
}
class JoinedDto
{
private int leftId;
private int rightId;
private String text;
public JoinedDto(int leftId,int rightId,String text)
{
this.leftId = leftId;
this.rightId = rightId;
this.text = text;
}
public int getLeftId()
{
return leftId;
}
public int getRightId()
{
return rightId;
}
public int getText()
{
return text;
}
}
Collection<LeftDto> leftList = new ArrayList<>();
Collection<RightDto> rightList = new ArrayList<>();
可以像这样连接,
Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
.<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
.on(LeftFyo::getId, RightDto::getLeftId)
.transformDirect(selection -> new JoinedDto(selection.getLeft().getText()
, selection.getLeft().getId()
, selection.getRight().getId())
)
.list();
表达式
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
推荐文章
- 在流中使用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