首先,让我们看一下您目前所展示的方法的复杂性:
ifForMethod
执行k个检查,其中m个返回 true。对于这些m中的每一个,都存在对n 个对象的迭代。那么,复杂度是k+nm。
forIfMethod
迭代n 个对象并在每次迭代中执行k个比较。那么,复杂度是k+n(k-1)=nk。
在这两种情况下,所有k个条件都必须至少评估一次,因此这里的区别实际上在于nm和n(k-1)加数。渐近地,m只是k的一小部分(你说m大约是0.75k),所以它们都是 O( nk ),但是k+nm < k+n(k-1),所以ifForMethod
可能比forIfMethod
. 实际运行时间的差异将取决于诸如迭代数组所需的实际时间以及k的大小等因素. 您将开始处理诸如内存局部性之类的问题(对于您的对象和您的代码)。
不过,这是一种您可能会觉得有趣的方法。理想情况下,您只想遍历对象列表一次,而不必多次检查布尔条件。您可以抽象出您正在执行的操作,这样您就可以将它们组合成一个单独的操作(并且您只会合并那些与真实条件相对应的操作),然后执行该复合操作列表中的每个元素。这是一些执行此操作的代码。
这个想法是有动作,你可以构造一个执行doA
的动作和一个执行的动作doB
。根据条件,您可以创建一个复合动作,其中包括条件为真时的动作和条件为真时doA
的动作。然后您遍历对象,并调用对每个对象执行复合操作。渐近地说,这是一种k+nm方法,所以理论上它表现得很好,但同样,这里的实际性能将取决于一些棘手的常数和内存局部性问题。doA
doB
doB
import java.util.ArrayList;
import java.util.List;
public class CompoundActionExample {
/**
* An action is used to do something to an argument.
*/
interface Action {
void act( Object argument );
}
/**
* A compound action is an action that acts on an argument
* by passing the argument to some other actions.
*/
static class CompoundAction implements Action {
/**
* The list of actions that the compound action will perform. Additional
* actions can be added using {@link #add(Action)}, and this list is only
* accessed through the {@link #act(Object)} method.
*/
private final List<CompoundActionExample.Action> actions;
/**
* Create a compound action with the specified list of actions.
*/
CompoundAction( final List<CompoundActionExample.Action> actions ) {
this.actions = actions;
}
/**
* Create a compound action with a fresh list of actions.
*/
CompoundAction() {
this( new ArrayList<CompoundActionExample.Action>() );
}
/**
* Add an action to the compound action.
*/
public void add( CompoundActionExample.Action action ) {
actions.add( action );
}
/**
* Act on an argument by passing the argument to each of the
* compound action's actions.
*/
public void act( final Object argument) {
for ( CompoundActionExample.Action action : actions ) {
action.act( argument );
}
}
}
public static void main(String[] args) {
// Some conditions and a list of objects
final boolean conditionA = true;
final boolean conditionB = false;
final Object[] listOfObjects = { "object1", "object2", "object3" };
// A compound action that encapsulates all the things you want to do
final CompoundAction compoundAction = new CompoundAction();
// If conditionA is true, add an action to the compound action that
// will perform doA. conditionA is evaluated exactly once.
if ( conditionA ) {
compoundAction.add( new Action() {
public void act( final Object argument) {
System.out.println( "doA("+argument+")" ); // doA( argument );
}
});
}
// If conditionB is true, add an action to the compound action that
// will perform doB. conditionB is evaluted exactly once.
if ( conditionB ) {
compoundAction.add( new Action() {
public void act(Object argument) {
System.out.println( "doB("+argument+")" ); // doB( argument );
}
});
}
// For each object, apply the compound action
for ( final Object o : listOfObjects ) {
compoundAction.act( o );
}
}
}