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();
}