Java 带开关的回路与不同回路

Java 带开关的回路与不同回路,java,performance,Java,Performance,我有一个方法,可以在用户元素上循环,并根据给定的约束设置布尔值: public void checkUsers( int constraint ) { for(int i=0; i<nodeUsers().size(); i++) { UserElement elem = nodeUsers().getUsersElementAt(i); switch (constraint) { case CHECK_ALL:

我有一个方法,可以在用户元素上循环,并根据给定的约束设置布尔值:

public void checkUsers( int constraint ) {
    for(int i=0; i<nodeUsers().size(); i++) {
        UserElement elem = nodeUsers().getUsersElementAt(i);

        switch (constraint) {
          case CHECK_ALL:
              elem.setChecked(true); break;
          case CHECK_NONE:
               elem.setChecked(false); break;
          case CHECK_NO_LANG:
               if (elem.getLanguage() == null)
                   elem.setChecked(true);
               else
                   elem.setChecked(false);
               break;
          // More cases         
        }
    }
}
public void checkUsers(int约束){

对于(int i=0;i这两个方法的实现更好。您的代码将更容易让其他人理解,因为他们只需要读取方法名称,而不必理解您的参数在第一个实现中的作用。

我不明白为什么不这样做,只要您正确地记录了一切:)

您可以提前计算循环的长度(节省时间和资源)
所以

节点用户().size() ->将其设为变量:)


祝你好运:)

第二个会稍微好一点,但它会根据你的JIT设置而有所不同

在最坏的情况下,每次迭代都会检查约束,这可能会导致性能下降。在最好的情况下,约束只检查一次

一种替代解决方案,它具有所有的优点,但没有任何潜在的缺点:

public void checkUsers(bool setTo) {
    for(int i=0; i<nodeUsers().size(); i++) {
        UserElement elem = nodeUsers().getUsersElementAt(i);
        elem.setChecked(setTo); break;  
    }
public void checkUsers(bool setTo){

对于(int i=0;i,在我看来,通过使约束成为真正的枚举,您可以更有效地执行此操作:

public enum Constraint
{
    CHECK_NONE
    {
        @Override void apply(UserElement element)
        {
            element.setChecked(false);
        }
    },
    CHECK_ALL
    {
        @Override void apply(UserElement element)
        {
            element.setChecked(true);
        }
    };

    public abstract void apply(UserElement element);
}
然后你可以有:

public void checkUsers(Constraint constraint) {
    for(int i=0; i<nodeUsers().size(); i++) {
        UserElement elem = nodeUsers().getUsersElementAt(i);
        constraint.apply(elem);
    }
}
public void checkUsers(约束){

对于(inti=0;i,如果您被困在1.4中,我建议将case语句从循环中提取出来,这样虽然您不会避免条件语句,但至少可以将其隔离。循环变得更简单,圈复杂度降低,当您切换到更现代的Java时,您可以看到更少的代码进行转换(好的,在一个函数中,您将升级到利用foreach;在另一个函数中,您将利用更好的枚举-但这是一个分离的关注点):

public void checkUsers(int约束){
对于(int i=0;i

这与您是否将单个案例拆分为各自的函数无关。

这是访问者模式的正常变化。缺少泛型支持并不是什么问题,因为您只分派一种类型的值。接口(或抽象类型)实现似乎是最正确的;如果您的部署案例使依赖项注入成为一个有吸引力的选项,那么这既允许更简单的单元测试,又为更好的可扩展性打开了大门。

哦,见鬼。这更好:

private void checkUser(int constraint, UserElement elem) {
    elem.setChecked(shouldCheck(constraint, elem));
}

private boolean shouldCheck(int constraint, UserElement elem) {
    switch (constraint) {
    case CHECK_ALL: return true;
    case CHECK_NONE:    return false;
    case CHECK_NO_LANG: return elem.getLanguage() == null;
    // More cases
    }
}

您避免了所有的中断s.

您在评论中提到您被困在1.4中,因此这应该让您开始使用类似于Jon Skeet建议的内容,但作为一个类型安全枚举

public abstract class Constraint {
  public static final Constraint CHECK_NONE = new Constraint(){
      @Override 
      public void apply(UserElement elem) {
        elem.setChecked(false);
      }
    };
  // etc. for other cases...

  // reduce visibility of ctor
  private Constraint() {};

  public abstract void apply();
}
用法与Jon Skeet的答案相同


请注意,只有当您仍停留在1.4上时才需要此选项。如果您使用的是现代Java,请使用真正的枚举。

我本来打算发布一个相反的答案,但在阅读此内容后,将其分开实际上更有意义。但请注意他的评论,//更多案例”。我们不知道有多少,但一旦你超过2,继续编写内部行为略有不同的相同循环的方法似乎是相当愚蠢的。JIT编译器为你做了这件事。噢,我陷入了特定的问题,而不是着眼于全局。+1我被Java 1.4困在这里,所以没有枚举。int不是吗eFace方法有点过头了吗?@Lieven:如果你真的有更多像你在代码中的评论所说的那样的情况,这绝对是一个好办法。更加灵活,你的循环方法也不会变得如此臃肿。Java中枚举类型的功能…哦,我喜欢。@Lieven:没有像过头一样的杀死。如果你被困在1.4中,请使用类型安全枚举模式。只需给它一个私有构造函数,并在其中包含一些类的公共静态最终实例。它们仍然可以是匿名内部类。正如我在回答中提到的,
break
不属于该类。我会修改此回答,使setTo参数的默认值为“true”。这样调用checkUsers()执行您期望的操作,并且checkUsers(false)将取消选中它们,这也不奇怪。@rmeador:Java中没有默认参数。获得此效果的唯一方法是创建一个调用checkUsers(true)的无参数重载。我想看看更复杂的案例是什么样的会很有用。有些答案实际上是基于这样的假设,即全部或全部都不是唯一的选项。在看到编辑后:Jon Skeet获胜。其他人应该删除他们的答案,因为他们不再真正回答问题。PS:对于最后一个案例,我只使用elem.s艾切克(elem.getLanguage()==null);卡尔:你应该刚刚编辑了你的原始帖子。好的,谢谢。我应该现在就编辑,还是时间太长了,这无关紧要?
private void checkUser(int constraint, UserElement elem) {
    elem.setChecked(shouldCheck(constraint, elem));
}

private boolean shouldCheck(int constraint, UserElement elem) {
    switch (constraint) {
    case CHECK_ALL: return true;
    case CHECK_NONE:    return false;
    case CHECK_NO_LANG: return elem.getLanguage() == null;
    // More cases
    }
}
public abstract class Constraint {
  public static final Constraint CHECK_NONE = new Constraint(){
      @Override 
      public void apply(UserElement elem) {
        elem.setChecked(false);
      }
    };
  // etc. for other cases...

  // reduce visibility of ctor
  private Constraint() {};

  public abstract void apply();
}