【问题标题】:Java simplifying repetitive code involving boolean comparisonJava简化涉及布尔比较的重复代码
【发布时间】:2021-08-14 03:43:43
【问题描述】:

我正在尝试找到一种方法来减少长度并简化以下重复方法:

boolean circleFlag, squareFlag, diamondFlag;

public void shapeButtonPressed(String shapeType) {

    if (shapeType.equals("Circle")) {
        circlePressed();
    } else if (shapeType.equals("Square")) {
        squarePressed();
    } else if (shapeType.equals("Diamond")) {
        diamondPressed();   
    }

}

public void circlePressed() {
    if(!circleFlag){
        //set only circleFlag true and the rest false.
        circleFlag = true;
        squareFlag = false;
        diamondFlag = false;

        //(... some code)
    } else {
        //set all flags false.
        circleFlag = false; 
        diamondFlag = false
        squareFlag = false;

        //(... some different code)
    }

}
public void squarePressed() {
    if(!squareFlag){
        //set only squareFlag true and the rest false.
        squareFlag = true;
        circleFlag = false;
        diamondFlag = false;

        //(... some code)
    } else {
        //set all flags false.
        circleFlag = false; 
        diamondFlag = false
        squareFlag = false;

        //(... some different code)
    }

}
public void diamondPressed() {
    if(!diamondFlag){
        //set only diamondFlag true and the rest false.
        diamondFlag = true;
        squareFlag = false;
        circleFlag = false;

        //(... some code)
    } else {
        //set all flags false.
        circleFlag = false; 
        diamondFlag = false
        squareFlag = false;

        //(... some different code)
    }
}

我尝试过的事情

我尝试将我的所有值设置为Boolean 类型,将它们设置为ArrayList<Boolean> 并将shapePressed(String shapeType) 方法更改为

public void shapePressed(String shapeType) {

    Boolean currFlag = false;

    if (shapeType.equals("Circle")) {
        currFlag = circleFlag;
    } else if (shapeType.equals("Square")) {
        currFlag = squareFlag;
    } else if (shapeType.equals("Diamond")) {
        currFlag = diamondFlag;
    }

    if (!currFlag){
        for (Boolean flag : shapeFlag) flag = ( flag == currFlag ) ? true : false; 

        //(...)
    } else {
        for (Boolean flag : shapeFlag) flag = false;

        //(...)
    }
}

( flag == currFlag ) 行将布尔值作为值而不是单个对象进行比较。所以我的currFlag在上面这个方法中是没有意义的。

然后我虽然使用HashMap<String ,Boolean>,但是每当我比较给定键的值(来自方法参数的字符串 shapeType)时,我都会遇到与上述相同的问题。

有什么方法可以简化这段代码?

【问题讨论】:

  • 您可以直接使用circleFlag = !circleFlag; 而不是if (circleFlag) { ...},然后将其他标志设置为false。
  • 可能有很多方法可以实现这一点,但我可能会建议使用 Enum 来表示您的不同形状并存储代表当前形状的 Enum 类型的 currFlag。跨度>

标签: java simplify


【解决方案1】:

当一个给定的形状被激活时,你只需反转那个标志。然后其他标志设置为 false。

因此,简单地说,您可以将 circlePressed() 逻辑简化为:

public void circlePressed() {
    circleFlag = !circleFlag;
    squareFlag = false;
    diamondFlag = false;

}

当然还有很多重复。您可以将其进一步重构为枚举并在那里跟踪状态。

public enum Flag {
  CIRCLE( false ),
  SQUARE( false ),
  DIAMOND( false ); // default state is false for all

  private boolean state;
  private Flag(boolean state) {
    this.state = state;
  }

  public void flipState() {
    this.state = !this.state;
  }

  public void setState(boolean state) {
    this.state = state;
  }
}

// notice this method takes the Flag not a string
public void shapeButtonPressed(Flag selected) {

    // iterate through all the flags ...
    for( Flag flag : Flag.values() ) {
        if (flag == selected) {
            // invert the "pressed" flag state
            flag.flipState();
        } else {
            // ... and set the rest to false
            flag.setState(false);
        }
    }
}

枚举的内置 values 方法返回所有已定义枚举的列表,因此我们可以遍历它们。

我承认这有点花哨,因为它并不是枚举的真正用途,但它大大简化了你的逻辑。

【讨论】:

  • 我不太明白在三个变量中跟踪状态的意义,如果只有一个变量可以同时为真的话。
  • activeState 变量可能有意义,但不幸的是,我们对围绕代码 sn-p 的用例知之甚少。
【解决方案2】:

你可以使用枚举。

public enum Shape {
  CIRCLE, SQUARE, DIAMOND
}

然后,像这样在你的代码中使用它;

Shape shape;

public void shapeButtonPressed(Shape selectedShape) {
    shape = selectedShape;
}

如果你不能改变shapeButtonPressed的方法签名并且它必须接受一个String,你仍然可以这样做

Shape shape;

public void shapeButtonPressed(String shapeType) {
    if (shapeType.equals("Circle")) {
        shape = Shape.CIRCLE;
    } else if (shapeType.equals("Square")) {
        shape = Shape.SQUARE;
    } else if (shapeType.equals("Diamond")) {
        shape = Shape.DIAMOND;
    }

}

【讨论】:

  • 可以更聪明地选择正确的枚举而不是if 链。例如,您可以根据其名称进行选择。您还可以在为您进行映射的枚举类中引入一个静态函数。这只是一个概念证明,并不是最复杂的解决方法。
  • 如果 OP 需要能够在按下相同的形状按钮时“取消选择”一个形状,也可以简单地修改代码以设置 shape = nullshape == shapeType 表示没有选择.
  • @JohannesH。谢谢,我忘记了枚举。但是,稍后在我的代码中,在其他方法中,我有时会遇到类似if(circleFlag || squareFlag || diamondFlag) { //(...) } 的内容。这是否意味着我不能使用您提供的方法?
  • 您只需要更改代码。您可以使用if (shape == Shape.SQUARE || shape == Shape.DIAMOND || shape == Shape.CIRCLE) {...} 或者,如果没有更多这三个形状,只需使用if (shape != null) {...}
  • @JohannesH 哦,对了,太棒了!非常感谢您的帮助:)。
【解决方案3】:

作为上述枚举方法的替代方法(我强烈推荐这个方法),您可以使用位掩码而不是布尔标志来执行更“C 风格”的解决方案。

位掩码本质上是一个数字(或二进制)值,其中每个位代表一个布尔值。

int shapeFlags;

public void shapeButtonPressed(String shapeType) {
    if (shapeType.equals("Circle")) {
        shapeFlags = 1;
    } else if (shapeType.equals("Square")) {
        shapeFlags = 2;
    } else if (shapeType.equals("Diamond")) {
        shapeFlags = 4;
    }
}

这仍然让您可以选择将多个形状设置为 true,同时能够在单个操作中覆盖所有标志。

从数值到形状的映射如下所示:

0 : no shape
1 : circle
2 : square
3 : circle & square
4 : diamond
5 : diamond & circle
6 : diamond & square
7 : all three

【讨论】:

    猜你喜欢
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 2016-01-25
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多