我有Collection<A>
class A {
String name;
Long id;
}
现在我有UI屏幕,我可以提供姓名&amp; id值以匹配此集合并显示结果。
现在我有3个标准:
我可以通过三次if
检查来检查基于UI字段的空检查,但我不想让if-else
阻止,因为如果我有多个UI文件,那么就会很忙嵌套if-else
检查。
请在java 7中建议更好的方法。
答案 0 :(得分:0)
您可以提供一些用于过滤集合的谓词。由于java.util.function.Predicate
仅添加了Java 8,因此您需要自行推送或使用Google Guava等库。
使用它可以传递要在过滤器中使用的谓词:
Collection<Predicate<A>> predicates = ...;//you get them from your UI
Collection<A> filtered = Collections2.filter( originalCollection, Preciates.and( predicates ) );
谓词可能如下所示:
class ANamePredicate implements Predicate<A> {
private String name;
public ANamePredicate( String n) {
name = n;
}
boolean apply(@Nullable A input) {
//if one or both could be null, add handling for that
return input.name.equals(n);
}
//implement equals(...) as well
}
当然你也可以使用匿名类,但是你可能想要提供一个抽象基类来消除总是实现equals()
的要求:
abstract class AbstractPredicate<T> implements Predicate<T> {
public boolean equals( Object o) {
//simplified, you might have to provide a better implementation, e.g. you want to provide a set of predicates
return false;
}
}
然后在需要时创建谓词集合:
Collection<Predicate<A>> predicates = new LinkedList<>();
predicates.add( new AbstractPredicate<A>() {
boolean apply(A input) {
return "Skabdus".equals(input.name);
}
} );
predicates.add( new AbstractPredicate<A>() {
boolean apply(A input) {
return input.id == 1;
}
} );
答案 1 :(得分:0)
您可以将装饰器模式与表达式一起使用。原则是要有一个接口,每个“标准”将实现(使用一种方法:eval),并区分终端运营商和终端运营商。
你有一个 NameIsSet 类,一个 IdIsSet 类作为终端操作符(或者如果你将来有其他实现,则为其他类),并且逻辑表达式为非终端运营商:和,或,不,......
然后,您应该以这种方式使用模式:
tableView
如果要为每种情况设置特定行为,可以创建这些谓词的List,并设置一个方法,如果谓词为true,则调用该方法:
Predicate predicate = new And(new IdIsSet("id"), new Not(new NameIsSet("name")));
if(predicate.eval()){
// Do something
}
以下是And class和NameIsSet类的示例:
for(Predicate predicate: predicateList){
if(predicate.eval()) {
predicate.execute();
//break if only one case is accepted
}
}
在此实现中,您必须事先创建所有谓词,将它们添加到列表中并为每个谓词设置execute()方法。
希望这对你有用。
答案 2 :(得分:0)
您的if
声明不需要嵌套。例如,您可以这样做:
static boolean matches(A candidate, A pattern) {
if (pattern.name != null && !candidate.name.equals(pattern.name))
return false;
if (pattern.id != null && !candidate.id.equals(pattern.id))
return false;
return true;
}
这可以按任意数量的字段以1:1的比例缩放。 (您可以在那里使用candidate.id != pattern.id
,但我使用equals
来保持一致性。)
如果您有数十个字段,并且不想单独命名,则可以使用反射并使用单个for
循环处理所有字段:
static boolean matches(A candidate, A pattern) throws IllegalAccessException {
for (Field fld : A.class.getDeclaredFields()) {
Object c = fld.get(candidate);
Object p = fld.get(pattern);
if (p != null && !c.equals(p))
return false;
}
return true;
}