简体   繁体   English

Java简化涉及boolean比较的重复代码

[英]Java simplifying repetitive code involving boolean comparison

I am trying to find a way to reduce the length and simplify the following repetitive methods:我试图找到一种方法来减少长度并简化以下重复方法:

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

Things I have tried我尝试过的事情

I have tried to set all my values to Boolean type, set them in a ArrayList<Boolean> and change the shapePressed(String shapeType) method to我试图将我所有的值设置为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;

        //(...)
    }
}

but the line ( flag == currFlag ) compares the booleans as values and not as individual objects.但是该行( flag == currFlag )将布尔值作为值而不是单个对象进行比较。 So my currFlag is pointless in this above method.所以我的currFlag在上面的方法中毫无意义。

I then though of using a HashMap<String,Boolean> but whenever I compare the values given a key (String shapeType from the method parameter), I encounter the same problem as above.然后我虽然使用了HashMap<String,Boolean>但是每当我比较给定键(方法参数中的 String shapeType)的值时,我都会遇到与上述相同的问题。

What is a way to simplify this code?有什么方法可以简化这段代码?

You could use an enum.您可以使用枚举。

public enum Shape {
  CIRCLE, SQUARE, DIAMOND
}

Then, use that in your code like so;然后,像这样在您的代码中使用它;

Shape shape;

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

If you can't change the method signature of shapeButtonPressed and it has to take a String, you can stil do如果您不能更改shapeButtonPressed的方法签名并且它必须采用字符串,您仍然可以这样做

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

}

When a given shape is activated, you just invert that flag.当给定的形状被激活时,您只需反转该标志。 Then the other flags get set to false.然后其他标志设置为 false。

So, trivially, you could simplify your circlePressed() logic to:因此,简单地说,您可以将circlePressed()逻辑简化为:

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

}

Of course there's still a lot of repetition.当然还是有很多重复的。 You could refactor this further to an enum and track the state there.您可以将其进一步重构为枚举并在那里跟踪 state。

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

The built-in values method on enums returns a list of all of the defined enums, so we can just iterate across them.枚举的内置values方法返回所有已定义枚举的列表,因此我们可以遍历它们。

It's a bit gimmicky, I admit, since it's not really what enums are intended for, but it simplifies your logic quite a bit.这有点花哨,我承认,因为它并不是枚举的真正目的,但它大大简化了您的逻辑。

As an alternative to my approach with enums above (that I highly recommend over this one), you can do a more "C-style" solution using a bitmask instead of boolean flags.作为我上面使用枚举的方法的替代方法(我强烈推荐这个方法),您可以使用位掩码而不是 boolean 标志来做一个更“C 风格”的解决方案。

A bitmask is essentially a numeric (or binary for that matter) value of which each bit represents a boolean value.位掩码本质上是一个数字(或二进制)值,其中每一位代表一个 boolean 值。

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

This still leaves you the option to set more than one shape to true while being able to override all flags in a single operation.这仍然让您可以选择将多个形状设置为true ,同时能够在单个操作中覆盖所有标志。

Mappings from numeric values to shapes would look like this:从数值到形状的映射如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM