【发布时间】:2013-02-07 10:25:27
【问题描述】:
我想要两个功能。第一个将给定一个集合,返回满足谓词的元素。谓词可能非常昂贵,并且结果不会被完全消耗,所以我认为最好的做法是返回一个视图。因此,一旦实现,我的方法就是封装了 Guava 的 Collections2.filter 的东西:
Collection<MyElement> getInterestingElements(Collection<MyElement> allElements) {
return Collections2.filter(allElements, new Predicate<MyElement>() {
@Override
public boolean apply(MyElement element) {
return element.isInteresting(); // call expensive function
}
});
}
(已更改类名以保护无辜者)
我的第二个函数将调用第一个函数并返回:
- 如果集合包含零个或多个元素,则为 null。
- 如果集合仅包含一个元素,则该集合的唯一元素。
也就是说,当且仅当此集合是单例时,此函数才会返回集合的内容。
一个简单的实现是:
MyElement getElementIfOnlyInterestingOne(Collection<MyElement> allElements) {
Collection<MyElement> interestingElements = getInterestingElements(allElements);
if (interestingElements.size() != 1){
return null;
}
return Iterables.first(interestingElements, null);
}
但是对size() 的调用(我认为)将评估基础集合中所有元素的谓词,而当我只对第一个元素感兴趣时,这是不可接受的。
我可以使用 Iterables.getOnlyElement() ,但如果集合不是单例,这会抛出异常,这应该经常发生,我认为依赖异常来做这件事是一种不好的做法。
所以我必须手动迭代,将第一个元素存储在一个变量中,如果有第二个元素则返回 null。
我的问题是:这很好,但我不是在重新发明轮子吗? Guava 有这么多的魔力,这个问题必须通过 isSingleton 或 getSingleElementOrNull 在某个地方解决:)
【问题讨论】: