假设您正在使用Java1.5,而您不能添加谷歌收藏,我会做一些与谷歌人非常相似的事情。这与乔恩的评论略有不同。
首先,将此接口添加到代码库中。public interface IPredicate { boolean apply(T type); }
当某个谓词对某一类型为真时,它的实施者可以回答。例如:如果T都是User和AuthorizedUserPredicate实施器IPredicate,然后AuthorizedUserPredicate#apply返回是否传入User是授权的。
然后在某个实用程序类中,你可以说public static Collection filter(Collection target, IPredicate predicate) {
Collection result = new ArrayList();
for (T element: target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;}
所以,假设您已经使用了上面的内容,那么Predicate isAuthorized = new Predicate() {
public boolean apply(User user) {
// binds a boolean method in User to a reference
return user.isAuthorized();
}};// allUsers is a CollectionCollection authorizedUsers = filter(allUsers, isAuthorized);
如果线性检查的性能受到关注,那么我可能希望有一个具有目标集合的域对象。具有目标集合的域对象将具有用于初始化、添加和设置目标集合的方法的筛选逻辑。
最新情况:
在实用工具类(假设谓词)中,我添加了一个SELECT方法,它在谓词不返回期望值时为默认值添加了一个选项,并为在新IPredicate中使用的Params添加了一个静态属性。public class Predicate {
public static Object predicateParams;
public static Collection filter(Collection target, IPredicate predicate) {
Collection result = new ArrayList();
for (T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
public static T select(Collection target, IPredicate predicate) {
T result = null;
for (T element : target) {
if (!predicate.apply(element))
continue;
result = element;
break;
}
return result;
}
public static T select(Collection target, IPredicate predicate, T defaultValue) {
T result = defaultValue;
for (T element : target) {
if (!predicate.apply(element))
continue;
result = element;
break;
}
return result;
}}
下面的示例查找集合之间缺少的对象:List missingObjects = (List) Predicate.filter(myCollectionOfA,
new IPredicate() {
public boolean apply(MyTypeA objectOfA) {
Predicate.predicateParams = objectOfA.getName();
return Predicate.select(myCollectionB, new IPredicate() {
public boolean apply(MyTypeB objectOfB) {
return objectOfB.getName().equals(Predicate.predicateParams.toString());
}
}) == null;
}
});
下面的示例在集合中查找实例,并在未找到实例时将集合的第一个元素作为默认值返回:MyType myObject = Predicate.select(collectionOfMyType, new IPredicate() {public boolean apply(MyType objectOfMyType) {
return objectOfMyType.isDefault();}}, collectionOfMyType.get(0));
更新(Java 8发布后):
自从我(Alan)第一次发布这个答案已经有好几年了,我仍然不敢相信我会为这个答案收集这么多的分数。无论如何,既然Java 8已经在语言中引入了闭包,我现在的回答就会大不相同,而且会更简单。使用Java 8,不需要单独的静态实用程序类。因此,如果您想找到与谓词匹配的第一个元素。final UserService userService = ... // perhaps injected IoCfinal Optional userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;}).findFirst();
用于选项的JDK 8 api具有以下能力:get(), isPresent(), orElse(defaultUser), orElseGet(userSupplier)和orElseThrow(exceptionSupplier),以及其他“一元”功能,例如map, flatMap和filter.
如果只想收集与谓词匹配的所有用户,则使用Collectors若要终止所需集合中的流,请执行以下操作。final UserService userService = ... // perhaps injected IoCfinal List userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;}).collect(Collectors.toList());
看见这里有关Java 8流如何工作的更多示例。